Commit 548b91ae authored by Rouslan Solomakhin's avatar Rouslan Solomakhin Committed by Commit Bot

[Payment Handler][CCT] 70% height payment handler window.

Before this patch, Chrome Custom Tab would always be 100% height in all
cases, including for showing a Payment Handler page. This hid the shop
page from the user and increased the chance of the shop page renderer
being killed.

This patch adds a PaymentHandlerActivity that extends CustomTabActivity
with a custom theme that has transparent background. The
PaymentHandler-specific functionality is moved from CustomTabActivity
into the PaymentHandlerActivity. This activity is 70% of the display
height ("bottom sheet"), unless that's less than 500dp, in which case
the height is 500dp. If a device rotates, the window is either in bottom
sheet or fullscreen mode, depending on the amount of available vertical
space.

The underlying activity is dimmed by DimmingDialog, which is a
fullscreen semi-transparent dialog. This was refactored out of
PaymentRequestUI, which now uses the DimmingDialog and optionally adds
opaque content at the bottom.

After this patch, payment handlers are displayed in a bottom sheet with
dimmed background.

Bug: 872833
Change-Id: I4c104373f3e44130d1217cbf2c6923be3b63d1a1
Reviewed-on: https://chromium-review.googlesource.com/1169636
Commit-Queue: Rouslan Solomakhin <rouslan@chromium.org>
Reviewed-by: default avatarPeter Conn <peconn@chromium.org>
Reviewed-by: default avatarTed Choc <tedchoc@chromium.org>
Cr-Commit-Position: refs/heads/master@{#594424}
parent 9e4de63f
...@@ -387,6 +387,15 @@ by a child template that "extends" this file. ...@@ -387,6 +387,15 @@ by a child template that "extends" this file.
{{ self.supports_vr() }} {{ self.supports_vr() }}
{{ self.extra_web_rendering_activity_definitions() }} {{ self.extra_web_rendering_activity_definitions() }}
</activity> </activity>
<activity android:name="org.chromium.chrome.browser.customtabs.PaymentHandlerActivity"
android:theme="@style/TranslucentMainTheme"
android:exported="false"
{{ self.chrome_activity_common() }}
{{ self.supports_video_persistence() }}
>
{{ self.supports_vr() }}
{{ self.extra_web_rendering_activity_definitions() }}
</activity>
<!-- SeparateTaskCustomTabActivity is a wrapper of CustomTabActivity. It provides the <!-- SeparateTaskCustomTabActivity is a wrapper of CustomTabActivity. It provides the
general feeling of supporting multi tasks, even for versions that did not fully support general feeling of supporting multi tasks, even for versions that did not fully support
it. it.
......
...@@ -42,6 +42,10 @@ ...@@ -42,6 +42,10 @@
<item name="android:windowSharedElementExitTransition" tools:targetApi="21">@transition/move_image</item> <item name="android:windowSharedElementExitTransition" tools:targetApi="21">@transition/move_image</item>
</style> </style>
<style name="MainTheme" parent="MainThemeBase" /> <style name="MainTheme" parent="MainThemeBase" />
<style name="TranslucentMainTheme" parent="MainThemeBase">
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowIsTranslucent">true</item>
</style>
<style name="MainButtonStyle" parent="ButtonCompatBorderless"> <style name="MainButtonStyle" parent="ButtonCompatBorderless">
<item name="android:textAppearance">@style/BlueButtonText2</item> <item name="android:textAppearance">@style/BlueButtonText2</item>
......
...@@ -430,6 +430,7 @@ ...@@ -430,6 +430,7 @@
<dimen name="payments_ui_max_dialog_width">0dp</dimen> <dimen name="payments_ui_max_dialog_width">0dp</dimen>
<dimen name="payments_ui_translation">100dp</dimen> <dimen name="payments_ui_translation">100dp</dimen>
<dimen name="payments_favicon_size">24dp</dimen> <dimen name="payments_favicon_size">24dp</dimen>
<dimen name="payments_handler_window_minimum_height">500dp</dimen>
<!-- Preferences dimensions <!-- Preferences dimensions
pref_autofill_field_horizontal_padding exists because TextInputLayouts have an internal pref_autofill_field_horizontal_padding exists because TextInputLayouts have an internal
......
...@@ -28,6 +28,7 @@ import org.chromium.base.metrics.CachedMetrics; ...@@ -28,6 +28,7 @@ import org.chromium.base.metrics.CachedMetrics;
import org.chromium.chrome.browser.browserservices.BrowserSessionContentUtils; import org.chromium.chrome.browser.browserservices.BrowserSessionContentUtils;
import org.chromium.chrome.browser.customtabs.CustomTabActivity; import org.chromium.chrome.browser.customtabs.CustomTabActivity;
import org.chromium.chrome.browser.customtabs.CustomTabIntentDataProvider; import org.chromium.chrome.browser.customtabs.CustomTabIntentDataProvider;
import org.chromium.chrome.browser.customtabs.PaymentHandlerActivity;
import org.chromium.chrome.browser.customtabs.SeparateTaskCustomTabActivity; import org.chromium.chrome.browser.customtabs.SeparateTaskCustomTabActivity;
import org.chromium.chrome.browser.firstrun.FirstRunFlowSequencer; import org.chromium.chrome.browser.firstrun.FirstRunFlowSequencer;
import org.chromium.chrome.browser.incognito.IncognitoDisclosureActivity; import org.chromium.chrome.browser.incognito.IncognitoDisclosureActivity;
...@@ -290,6 +291,13 @@ public class LaunchIntentDispatcher implements IntentHandler.IntentHandlerDelega ...@@ -290,6 +291,13 @@ public class LaunchIntentDispatcher implements IntentHandler.IntentHandlerDelega
newIntent.setData(uri); newIntent.setData(uri);
newIntent.setClassName(context, CustomTabActivity.class.getName()); newIntent.setClassName(context, CustomTabActivity.class.getName());
// Use a custom tab with a unique theme for payment handlers.
if (intent.getIntExtra(CustomTabIntentDataProvider.EXTRA_UI_TYPE,
CustomTabIntentDataProvider.CustomTabsUiType.DEFAULT)
== CustomTabIntentDataProvider.CustomTabsUiType.PAYMENT_REQUEST) {
newIntent.setClassName(context, PaymentHandlerActivity.class.getName());
}
// If |uri| is a content:// URI, we want to propagate the URI permissions. This can't be // If |uri| is a content:// URI, we want to propagate the URI permissions. This can't be
// achieved by simply adding the FLAG_GRANT_READ_URI_PERMISSION to the Intent, since the // achieved by simply adding the FLAG_GRANT_READ_URI_PERMISSION to the Intent, since the
// data URI on the Intent isn't |uri|, it just has |uri| as a query parameter. // data URI on the Intent isn't |uri|, it just has |uri| as a query parameter.
......
...@@ -20,6 +20,7 @@ import android.os.Bundle; ...@@ -20,6 +20,7 @@ import android.os.Bundle;
import android.os.StrictMode; import android.os.StrictMode;
import android.os.SystemClock; import android.os.SystemClock;
import android.provider.Browser; import android.provider.Browser;
import android.support.annotation.CallSuper;
import android.support.annotation.IntDef; import android.support.annotation.IntDef;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.customtabs.CustomTabsIntent; import android.support.customtabs.CustomTabsIntent;
...@@ -83,7 +84,6 @@ import org.chromium.chrome.browser.incognito.IncognitoTabHost; ...@@ -83,7 +84,6 @@ import org.chromium.chrome.browser.incognito.IncognitoTabHost;
import org.chromium.chrome.browser.incognito.IncognitoTabHostRegistry; import org.chromium.chrome.browser.incognito.IncognitoTabHostRegistry;
import org.chromium.chrome.browser.net.spdyproxy.DataReductionProxySettings; import org.chromium.chrome.browser.net.spdyproxy.DataReductionProxySettings;
import org.chromium.chrome.browser.page_info.PageInfoController; import org.chromium.chrome.browser.page_info.PageInfoController;
import org.chromium.chrome.browser.payments.ServiceWorkerPaymentAppBridge;
import org.chromium.chrome.browser.rappor.RapporServiceBridge; import org.chromium.chrome.browser.rappor.RapporServiceBridge;
import org.chromium.chrome.browser.snackbar.SnackbarManager; import org.chromium.chrome.browser.snackbar.SnackbarManager;
import org.chromium.chrome.browser.tab.BrowserControlsVisibilityDelegate; import org.chromium.chrome.browser.tab.BrowserControlsVisibilityDelegate;
...@@ -780,7 +780,13 @@ public class CustomTabActivity extends ChromeActivity<CustomTabActivityComponent ...@@ -780,7 +780,13 @@ public class CustomTabActivity extends ChromeActivity<CustomTabActivityComponent
return asyncParams.getWebContents(); return asyncParams.getWebContents();
} }
private void initializeMainTab(Tab tab) { /**
* Initializes tab handlers and observers, e.g., for metrics.
*
* @param tab The tab to initialize.
*/
@CallSuper
protected void initializeMainTab(Tab tab) {
TabRedirectHandler.from(tab).updateIntent(getIntent()); TabRedirectHandler.from(tab).updateIntent(getIntent());
tab.getView().requestFocus(); tab.getView().requestFocus();
...@@ -803,12 +809,6 @@ public class CustomTabActivity extends ChromeActivity<CustomTabActivityComponent ...@@ -803,12 +809,6 @@ public class CustomTabActivity extends ChromeActivity<CustomTabActivityComponent
// Immediately add the observer to PageLoadMetrics to catch early events that may // Immediately add the observer to PageLoadMetrics to catch early events that may
// be generated in the middle of tab initialization. // be generated in the middle of tab initialization.
mTabObserverRegistrar.addObserversForTab(tab); mTabObserverRegistrar.addObserversForTab(tab);
// Let ServiceWorkerPaymentAppBridge observe the opened tab for payment request.
if (mIntentDataProvider.isForPaymentRequest()) {
ServiceWorkerPaymentAppBridge.addTabObserverForPaymentRequestTab(tab);
}
prepareTabBackground(tab); prepareTabBackground(tab);
} }
...@@ -1144,13 +1144,6 @@ public class CustomTabActivity extends ChromeActivity<CustomTabActivityComponent ...@@ -1144,13 +1144,6 @@ public class CustomTabActivity extends ChromeActivity<CustomTabActivityComponent
if (mIsClosing) return; if (mIsClosing) return;
mIsClosing = true; mIsClosing = true;
// Notify the window is closing so as to abort invoking payment app early.
if (mIntentDataProvider.isForPaymentRequest()
&& getActivityTab().getWebContents() != null) {
ServiceWorkerPaymentAppBridge.onClosingPaymentAppWindow(
getActivityTab().getWebContents());
}
if (!reparenting) { if (!reparenting) {
// Closing the activity destroys the renderer as well. Re-create a spare renderer some // Closing the activity destroys the renderer as well. Re-create a spare renderer some
// time after, so that we have one ready for the next tab open. This does not increase // time after, so that we have one ready for the next tab open. This does not increase
......
...@@ -402,9 +402,10 @@ public class CustomTabIntentDataProvider extends BrowserSessionDataProvider { ...@@ -402,9 +402,10 @@ public class CustomTabIntentDataProvider extends BrowserSessionDataProvider {
/** /**
* @return Whether url bar hiding should be enabled in the custom tab. Default is false. * @return Whether url bar hiding should be enabled in the custom tab. Default is false.
* It should be impossible to hide the url bar when the tab is opened for Payment Request.
*/ */
public boolean shouldEnableUrlBarHiding() { public boolean shouldEnableUrlBarHiding() {
return mEnableUrlBarHiding; return mEnableUrlBarHiding && !isForPaymentRequest();
} }
/** /**
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.customtabs;
import android.view.Gravity;
import android.view.WindowManager;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.payments.ServiceWorkerPaymentAppBridge;
import org.chromium.chrome.browser.tab.Tab;
/**
* Simple wrapper around CustomTabActivity to be used when launching a payment handler tab, which
* uses a different theme.
*/
public class PaymentHandlerActivity extends CustomTabActivity {
private static final double BOTTOM_SHEET_HEIGHT_RATIO = 0.7;
private boolean mHaveNotifiedServiceWorker;
@Override
protected void initializeMainTab(Tab tab) {
super.initializeMainTab(tab);
ServiceWorkerPaymentAppBridge.addTabObserverForPaymentRequestTab(tab);
}
@Override
public void preInflationStartup() {
super.preInflationStartup();
int heightInPhysicalPixels = (int) (getWindowAndroid().getDisplay().getDisplayHeight()
* BOTTOM_SHEET_HEIGHT_RATIO);
int minimumHeightInPhysicalPixels = getResources().getDimensionPixelSize(
R.dimen.payments_handler_window_minimum_height);
if (heightInPhysicalPixels < minimumHeightInPhysicalPixels)
heightInPhysicalPixels = minimumHeightInPhysicalPixels;
WindowManager.LayoutParams attributes = getWindow().getAttributes();
attributes.height = heightInPhysicalPixels;
attributes.gravity = Gravity.BOTTOM;
getWindow().setAttributes(attributes);
}
@Override
protected void handleFinishAndClose() {
// Notify the window is closing so as to abort invoking payment app early.
if (!mHaveNotifiedServiceWorker && getActivityTab().getWebContents() != null) {
mHaveNotifiedServiceWorker = true;
ServiceWorkerPaymentAppBridge.onClosingPaymentAppWindow(
getActivityTab().getWebContents());
}
super.handleFinishAndClose();
}
}
\ No newline at end of file
...@@ -692,6 +692,7 @@ public class PaymentRequestImpl ...@@ -692,6 +692,7 @@ public class PaymentRequestImpl
&& !mIsUserGestureShow)) { && !mIsUserGestureShow)) {
mUI.show(); mUI.show();
} else { } else {
mUI.dimBackground();
mDidRecordShowEvent = true; mDidRecordShowEvent = true;
mShouldRecordAbortReason = true; mShouldRecordAbortReason = true;
mJourneyLogger.setEventOccurred(Event.SKIPPED_SHOW); mJourneyLogger.setEventOccurred(Event.SKIPPED_SHOW);
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.payments.ui;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.support.v4.view.animation.FastOutLinearInInterpolator;
import android.support.v4.view.animation.LinearOutSlowInInterpolator;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnLayoutChangeListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.Window;
import android.widget.FrameLayout;
import org.chromium.base.ApiCompatibilityUtils;
import org.chromium.base.VisibleForTesting;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.widget.AlwaysDismissedDialog;
import org.chromium.chrome.browser.widget.animation.AnimatorProperties;
/**
* A fullscreen semitransparent dialog used for dimming Chrome when overlaying a bottom sheet
* dialog/CCT or an alert dialog on top of it. FLAG_DIM_BEHIND is not being used because it causes
* the web contents of a payment handler CCT to also dim on some versions of Android (e.g., Nougat).
*/
/* package */ class DimmingDialog {
/**
* Length of the animation to either show the UI or expand it to full height. Note that click of
* 'Pay' button in PaymentRequestUI is not accepted until the animation is done, so this
* duration also serves the function of preventing the user from accidentally double-clicking on
* the screen when triggering payment and thus authorizing unwanted transaction.
*/
private static final int DIALOG_ENTER_ANIMATION_MS = 225;
/** Length of the animation to hide the bottom sheet UI. */
private static final int DIALOG_EXIT_ANIMATION_MS = 195;
private final Dialog mDialog;
private final ViewGroup mFullContainer;
private final int mAnimatorTranslation;
private boolean mIsAnimatingDisappearance;
/**
* Builds the dimming dialog.
*
* @param activity The activity on top of which the dialog should be displayed.
* @param dismissListener The listener for the dismissal of this dialog.
*/
/* package */ DimmingDialog(
Activity activity, DialogInterface.OnDismissListener dismissListener) {
// To handle the specced animations, the dialog is entirely contained within a translucent
// FrameLayout. This could eventually be converted to a real BottomSheetDialog, but that
// requires exploration of how interactions would work when the dialog can be sent back and
// forth between the peeking and expanded state.
mFullContainer = new FrameLayout(activity);
mFullContainer.setBackgroundColor(ApiCompatibilityUtils.getColor(
activity.getResources(), R.color.modal_dialog_scrim_color));
mDialog = new AlwaysDismissedDialog(activity, R.style.DialogWhenLarge);
mDialog.setOnDismissListener(dismissListener);
mDialog.addContentView(mFullContainer,
new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
Window dialogWindow = mDialog.getWindow();
dialogWindow.setGravity(Gravity.CENTER);
dialogWindow.setLayout(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
dialogWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
mAnimatorTranslation =
activity.getResources().getDimensionPixelSize(R.dimen.payments_ui_translation);
}
/** @param bottomSheetView The view to show in the bottom sheet. */
/* package */ void addBottomSheetView(View bottomSheetView) {
FrameLayout.LayoutParams bottomSheetParams =
new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
bottomSheetParams.gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
mFullContainer.addView(bottomSheetView, bottomSheetParams);
bottomSheetView.addOnLayoutChangeListener(new FadeInAnimator());
}
/** Show the dialog. */
/* package */ void show() {
mDialog.show();
}
/** Hide the dialog without dismissing it. */
/* package */ void hide() {
mDialog.hide();
}
/**
* Dismiss the dialog.
*
* @param isAnimated If true, the dialog dismissal is animated.
*/
/* package */ void dismiss(boolean isAnimated) {
if (!mDialog.isShowing()) return;
if (isAnimated) {
new DisappearingAnimator(true);
} else {
mDialog.dismiss();
}
}
/** @param overlay The overlay to show. This can be an error dialog, for example. */
/* package */ void showOverlay(View overlay) {
// Animate the bottom sheet going away.
new DisappearingAnimator(false);
int floatingDialogWidth = DimmingDialog.computeMaxWidth(mFullContainer.getContext(),
mFullContainer.getMeasuredWidth(), mFullContainer.getMeasuredHeight());
FrameLayout.LayoutParams overlayParams =
new FrameLayout.LayoutParams(floatingDialogWidth, LayoutParams.WRAP_CONTENT);
overlayParams.gravity = Gravity.CENTER;
mFullContainer.addView(overlay, overlayParams);
}
/** @return Whether the dialog is currently animating disappearance. */
/* package */ boolean isAnimatingDisappearance() {
return mIsAnimatingDisappearance;
}
/**
* Computes the maximum possible width for a dialog box.
*
* Follows https://www.google.com/design/spec/components/dialogs.html#dialogs-simple-dialogs
*
* @param context Context to pull resources from.
* @param availableWidth Available width for the dialog.
* @param availableHeight Available height for the dialog.
* @return Maximum possible width for the dialog box.
*
* TODO(dfalcantara): Revisit this function when the new assets come in.
* TODO(dfalcantara): The dialog should listen for configuration changes and resize accordingly.
*/
private static int computeMaxWidth(Context context, int availableWidth, int availableHeight) {
int baseUnit = context.getResources().getDimensionPixelSize(R.dimen.dialog_width_unit);
int maxSize = Math.min(availableWidth, availableHeight);
int multiplier = maxSize / baseUnit;
return multiplier * baseUnit;
}
/**
* Animates the whole dialog fading in and darkening everything else on screen.
* This particular animation is not tracked because it is not meant to be cancellable.
*/
private class FadeInAnimator extends AnimatorListenerAdapter implements OnLayoutChangeListener {
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft,
int oldTop, int oldRight, int oldBottom) {
mFullContainer.getChildAt(0).removeOnLayoutChangeListener(this);
Animator scrimFader = ObjectAnimator.ofInt(mFullContainer.getBackground(),
AnimatorProperties.DRAWABLE_ALPHA_PROPERTY, 0, 255);
Animator alphaAnimator = ObjectAnimator.ofFloat(mFullContainer, View.ALPHA, 0f, 1f);
AnimatorSet alphaSet = new AnimatorSet();
alphaSet.playTogether(scrimFader, alphaAnimator);
alphaSet.setDuration(DIALOG_ENTER_ANIMATION_MS);
alphaSet.setInterpolator(new LinearOutSlowInInterpolator());
alphaSet.start();
}
}
/** Animates the bottom sheet (and optionally, the scrim) disappearing off screen. */
private class DisappearingAnimator extends AnimatorListenerAdapter {
private final boolean mIsDialogClosing;
/* package */ DisappearingAnimator(boolean removeDialog) {
mIsDialogClosing = removeDialog;
View child = mFullContainer.getChildAt(0);
assert child != null;
Animator sheetFader = ObjectAnimator.ofFloat(child, View.ALPHA, child.getAlpha(), 0f);
Animator sheetTranslator =
ObjectAnimator.ofFloat(child, View.TRANSLATION_Y, 0f, mAnimatorTranslation);
AnimatorSet current = new AnimatorSet();
current.setDuration(DIALOG_EXIT_ANIMATION_MS);
current.setInterpolator(new FastOutLinearInInterpolator());
if (mIsDialogClosing) {
Animator scrimFader = ObjectAnimator.ofInt(mFullContainer.getBackground(),
AnimatorProperties.DRAWABLE_ALPHA_PROPERTY, 127, 0);
current.playTogether(sheetFader, sheetTranslator, scrimFader);
} else {
current.playTogether(sheetFader, sheetTranslator);
}
mIsAnimatingDisappearance = true;
current.addListener(this);
current.start();
}
@Override
public void onAnimationEnd(Animator animation) {
mIsAnimatingDisappearance = false;
mFullContainer.removeView(mFullContainer.getChildAt(0));
if (mIsDialogClosing && mDialog.isShowing()) mDialog.dismiss();
}
}
@VisibleForTesting
public Dialog getDialogForTest() {
return mDialog;
}
}
...@@ -8,10 +8,8 @@ import android.content.Context; ...@@ -8,10 +8,8 @@ import android.content.Context;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.support.v4.view.MarginLayoutParamsCompat; import android.support.v4.view.MarginLayoutParamsCompat;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.FrameLayout;
import org.chromium.chrome.R; import org.chromium.chrome.R;
import org.chromium.chrome.browser.widget.BoundedLinearLayout; import org.chromium.chrome.browser.widget.BoundedLinearLayout;
...@@ -49,19 +47,11 @@ public class PaymentRequestUiErrorView extends BoundedLinearLayout { ...@@ -49,19 +47,11 @@ public class PaymentRequestUiErrorView extends BoundedLinearLayout {
} }
/** /**
* Shows the dialog by attaching it to the given parent. * Sets the callback to run upon hitting the OK button.
* *
* @param parent Parent to attach to.
* @param callback Callback to run upon hitting the OK button. * @param callback Callback to run upon hitting the OK button.
*/ */
public void show(ViewGroup parent, final Runnable callback) { public void setDismissRunnable(final Runnable callback) {
int floatingDialogWidth = PaymentRequestUiErrorView.computeMaxWidth(parent.getContext(),
parent.getMeasuredWidth(), parent.getMeasuredHeight());
FrameLayout.LayoutParams overlayParams =
new FrameLayout.LayoutParams(floatingDialogWidth, LayoutParams.WRAP_CONTENT);
overlayParams.gravity = Gravity.CENTER;
parent.addView(this, overlayParams);
// Make the user explicitly click on the OK button to dismiss the dialog. // Make the user explicitly click on the OK button to dismiss the dialog.
View confirmButton = findViewById(R.id.ok_button); View confirmButton = findViewById(R.id.ok_button);
confirmButton.setOnClickListener(new OnClickListener() { confirmButton.setOnClickListener(new OnClickListener() {
...@@ -80,25 +70,4 @@ public class PaymentRequestUiErrorView extends BoundedLinearLayout { ...@@ -80,25 +70,4 @@ public class PaymentRequestUiErrorView extends BoundedLinearLayout {
public void setBitmap(Bitmap bitmap) { public void setBitmap(Bitmap bitmap) {
((PaymentRequestHeader) findViewById(R.id.header)).setTitleBitmap(bitmap); ((PaymentRequestHeader) findViewById(R.id.header)).setTitleBitmap(bitmap);
} }
/**
* Computes the maximum possible width for a dialog box.
*
* Follows https://www.google.com/design/spec/components/dialogs.html#dialogs-simple-dialogs
*
* @param context Context to pull resources from.
* @param availableWidth Available width for the dialog.
* @param availableHeight Available height for the dialog.
* @return Maximum possible width for the dialog box.
*
* TODO(dfalcantara): Revisit this function when the new assets come in.
* TODO(dfalcantara): The dialog should listen for configuration changes and resize accordingly.
*/
public static int computeMaxWidth(Context context, int availableWidth, int availableHeight) {
int baseUnit = context.getResources().getDimensionPixelSize(R.dimen.dialog_width_unit);
int maxSize = Math.min(availableWidth, availableHeight);
int multiplier = maxSize / baseUnit;
int floatingDialogWidth = multiplier * baseUnit;
return floatingDialogWidth;
}
} }
...@@ -384,6 +384,7 @@ chrome_java_sources = [ ...@@ -384,6 +384,7 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/customtabs/FirstMeaningfulPaintObserver.java", "java/src/org/chromium/chrome/browser/customtabs/FirstMeaningfulPaintObserver.java",
"java/src/org/chromium/chrome/browser/customtabs/NavigationInfoCaptureTrigger.java", "java/src/org/chromium/chrome/browser/customtabs/NavigationInfoCaptureTrigger.java",
"java/src/org/chromium/chrome/browser/customtabs/PageLoadMetricsObserver.java", "java/src/org/chromium/chrome/browser/customtabs/PageLoadMetricsObserver.java",
"java/src/org/chromium/chrome/browser/customtabs/PaymentHandlerActivity.java",
"java/src/org/chromium/chrome/browser/customtabs/RequestThrottler.java", "java/src/org/chromium/chrome/browser/customtabs/RequestThrottler.java",
"java/src/org/chromium/chrome/browser/customtabs/SeparateTaskCustomTabActivity.java", "java/src/org/chromium/chrome/browser/customtabs/SeparateTaskCustomTabActivity.java",
"java/src/org/chromium/chrome/browser/customtabs/SeparateTaskCustomTabActivity0.java", "java/src/org/chromium/chrome/browser/customtabs/SeparateTaskCustomTabActivity0.java",
...@@ -1135,6 +1136,7 @@ chrome_java_sources = [ ...@@ -1135,6 +1136,7 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/widget/prefeditor/ExpandableGridView.java", "java/src/org/chromium/chrome/browser/widget/prefeditor/ExpandableGridView.java",
"java/src/org/chromium/chrome/browser/widget/prefeditor/HintedDropDownAdapter.java", "java/src/org/chromium/chrome/browser/widget/prefeditor/HintedDropDownAdapter.java",
"java/src/org/chromium/chrome/browser/widget/prefeditor/HintedDropDownAdapterWithPlusIcon.java", "java/src/org/chromium/chrome/browser/widget/prefeditor/HintedDropDownAdapterWithPlusIcon.java",
"java/src/org/chromium/chrome/browser/payments/ui/DimmingDialog.java",
"java/src/org/chromium/chrome/browser/payments/ui/LineItem.java", "java/src/org/chromium/chrome/browser/payments/ui/LineItem.java",
"java/src/org/chromium/chrome/browser/payments/ui/PaymentInformation.java", "java/src/org/chromium/chrome/browser/payments/ui/PaymentInformation.java",
"java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestBottomBar.java", "java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestBottomBar.java",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment