Skip to content

Commit

Permalink
Introduce OverlayWidget & Use it by PaymentHandler
Browse files Browse the repository at this point in the history
  • Loading branch information
MyidShin authored and javifernandez committed Dec 4, 2024
1 parent dd638d2 commit f225588
Show file tree
Hide file tree
Showing 9 changed files with 402 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.chromium.wolvic.DownloadManagerBridge;
import org.chromium.wolvic.PasswordForm;
import org.chromium.wolvic.PermissionManagerBridge;
import org.chromium.wolvic.TabCompositorView;
import org.chromium.wolvic.UserDialogManagerBridge;

import java.io.InputStream;
Expand Down Expand Up @@ -114,8 +115,8 @@ public void setActive(boolean active) {
if (mTab == null)
return;

assert mTab.getContentView() != null;
WebContents webContents = mTab.getContentView().getWebContents();
assert mTab.getActiveWebContents() != null;
WebContents webContents = mTab.getActiveWebContents();
if (active) {
webContents.onShow();
} else {
Expand All @@ -129,8 +130,8 @@ public void setActive(boolean active) {
public void setFocused(boolean focused) {
if (mTab == null)
return;
assert mTab.getContentView() != null;
mTab.getContentView().getWebContents().setFocus(focused);
assert mTab.getActiveWebContents() != null;
mTab.getActiveWebContents().setFocus(focused);
}

@Override
Expand Down Expand Up @@ -215,6 +216,20 @@ public void releaseDisplay(@NonNull WDisplay display) {
getTextInput().setView(null);
}

public WDisplay acquireOverlayDisplay(TabCompositorView compositorView) {
SettingsStore settings = SettingsStore.getInstance(mRuntime.getContext());
WDisplay display = new DisplayImpl(this, compositorView);
mRuntime.getContainerView().addView(compositorView,
new ViewGroup.LayoutParams(settings.getWindowWidth() / 2, settings.getWindowHeight() / 2));
getTextInput().setView(getContentView());
return display;
}

public void releaseOverlayDisplay(TabCompositorView compositorView) {
mRuntime.getContainerView().removeView(compositorView);
getTextInput().setView(null);
}

@Override
public void restoreState(@NonNull WSessionState state) {

Expand Down Expand Up @@ -457,7 +472,7 @@ public TabImpl getTab() {
}

public ViewGroup getContentView() {
return mTab != null ? mTab.getContentView() : null;
return mTab != null ? mTab.getActiveContentView() : null;
}

// The onReadyCallback() mechanism is really limited because it heavily depends on renderers
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,25 @@

import androidx.annotation.NonNull;

import org.chromium.components.embedder_support.view.ContentView;
import org.chromium.content_public.browser.MediaSessionObserver;
import org.chromium.content_public.browser.SelectionPopupController;
import org.chromium.content_public.browser.WebContents;
import org.chromium.wolvic.Tab;
import org.chromium.wolvic.TabCompositorView;

/**
* Controlls a single tab content in a browser for chromium backend.
* Controls a single tab content in a browser for chromium backend.
*/
public class TabImpl extends Tab {
private TabMediaSessionObserver mTabMediaSessionObserver;
private TabWebContentsDelegate mTabWebContentsDelegate;
private TabWebContentsObserver mWebContentsObserver;
private WebContents mPaymentHandlerWebContents;
// TODO: Need to Payment's mediator
private ContentView mPaymentHandlerContentView;
private TabCompositorView mPaymentHandlerCompositorView;


public TabImpl(@NonNull Context context, @NonNull SessionImpl session, WebContents webContents) {
super(context, session.getSettings().getUsePrivateMode(), webContents);
Expand All @@ -27,7 +34,7 @@ private void registerCallbacks(@NonNull SessionImpl session) {
mTabWebContentsDelegate = new TabWebContentsDelegate(session, mWebContents);
setWebContentsDelegate(mWebContents, mTabWebContentsDelegate);

mWebContentsObserver = new TabWebContentsObserver(mWebContents, session);
mWebContentsObserver = new TabWebContentsObserver(this, session);

SelectionPopupController controller =
SelectionPopupController.fromWebContents(mWebContents);
Expand All @@ -47,4 +54,22 @@ public void onMediaFullscreen(boolean isFullscreen) {
public void purgeHistory() {
mWebContents.getNavigationController().clearHistory();
}

public void setPaymentWebContents(WebContents webContents, ContentView contentView, TabCompositorView compositorView) {
mPaymentHandlerWebContents = webContents;
mPaymentHandlerContentView = contentView;
mPaymentHandlerCompositorView = compositorView;
}

public WebContents getActiveWebContents() {
return mPaymentHandlerWebContents != null ? mPaymentHandlerWebContents : mWebContents;
}

public ContentView getActiveContentView() {
return mPaymentHandlerContentView != null ? mPaymentHandlerContentView : getContentView();
}

public TabCompositorView getActiveCompositorView() {
return mPaymentHandlerCompositorView != null ? mPaymentHandlerCompositorView : getCompositorView();
}
}
Original file line number Diff line number Diff line change
@@ -1,24 +1,39 @@
package com.igalia.wolvic.browser.api.impl;

import android.content.Context;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.igalia.wolvic.browser.api.WDisplay;
import com.igalia.wolvic.browser.api.WSession;
import com.igalia.wolvic.browser.api.WWebRequestError;

import org.chromium.base.ContextUtils;
import org.chromium.components.embedder_support.view.ContentView;
import org.chromium.content_public.browser.LifecycleState;
import org.chromium.content_public.browser.LoadUrlParams;
import org.chromium.content_public.browser.NavigationHandle;
import org.chromium.content_public.browser.WebContents;
import org.chromium.content_public.browser.WebContentsObserver;
import org.chromium.ui.base.ActivityWindowAndroid;
import org.chromium.ui.base.IntentRequestTracker;
import org.chromium.ui.base.ViewAndroidDelegate;
import org.chromium.ui.base.WindowAndroid;
import org.chromium.url.GURL;
import org.chromium.wolvic.TabCompositorView;
import org.chromium.wolvic.WolvicWebContentsFactory;

import java.security.cert.X509Certificate;

public class TabWebContentsObserver extends WebContentsObserver {
private @NonNull SessionImpl mSession;
private @NonNull TabImpl mTab;
private WebContentsObserver mPaymentWebContentsObserver;

public TabWebContentsObserver(WebContents webContents, @NonNull SessionImpl session) {
super(webContents);
public TabWebContentsObserver(TabImpl tab, @NonNull SessionImpl session) {
super(tab.getActiveWebContents());
mTab = tab;
mSession = session;
}

Expand Down Expand Up @@ -106,6 +121,51 @@ public void didStopLoading(GURL url, boolean isKnownValid) {
dispatchCanGoBackOrForward();
}

@Override
public void onCreateNewPaymentHandler(final WebContents newWebContents) {
WSession.ContentDelegate contentDelegate = mSession.getContentDelegate();
if (contentDelegate == null) {
return;
}

assert newWebContents.getViewAndroidDelegate() != null
: "WebContents should be initialized.";
WindowAndroid windowAndroid = newWebContents.getTopLevelNativeWindow();
Context context = mWebContents.get().getTopLevelNativeWindow().getContext().get();
final TabCompositorView compositorView = new TabCompositorView(context);
compositorView.onNativeLibraryLoaded(windowAndroid);
windowAndroid.setAnimationPlaceholderView(compositorView);

ViewAndroidDelegate viewDelegate = newWebContents.getViewAndroidDelegate();
assert viewDelegate.getContainerView() instanceof ContentView
: "WebContents should not set container views other than ContentView.";

mTab.setPaymentWebContents(newWebContents, (ContentView) viewDelegate.getContainerView(), compositorView);

WDisplay display = mSession.acquireOverlayDisplay(compositorView);
contentDelegate.onShowPaymentHandler(mSession, display, () -> {
if (newWebContents.isDestroyed()) {
return;
}
mTab.setPaymentWebContents(null, null, null);
newWebContents.destroy();
});

// Show Compositor View after attaching to the parent view.
compositorView.setCurrentWebContents(newWebContents);

mPaymentWebContentsObserver = new WebContentsObserver(newWebContents) {
@Override
public void destroy() {
mSession.releaseOverlayDisplay(compositorView);
mTab.setPaymentWebContents(null, null, null);

contentDelegate.onHidePaymentHandler(mSession);
newWebContents.removeObserver(this);
}
};
}

@Override
public void didFailLoad(boolean isInPrimaryMainFrame, int errorCode, GURL failingUrl, @LifecycleState int rfhLifecycleState) {
@Nullable WSession.ProgressDelegate delegate = mSession.getProgressDelegate();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import org.chromium.content_public.browser.ImeAdapter;
import org.chromium.content_public.browser.InputMethodManagerWrapper;
import org.chromium.content_public.browser.WebContents;
import org.chromium.ui.base.WindowAndroid;

public class TextInputImpl implements WTextInput {
Expand Down Expand Up @@ -180,6 +181,7 @@ public WSession.TextInputDelegate getDelegate() {
}

private ImeAdapter getImeAdapter() {
return mSession.getTab() != null ? mSession.getTab().getImeAdapter() : null;
WebContents webContents = mSession.getTab() != null ? mSession.getTab().getActiveWebContents() : null;
return webContents != null ? ImeAdapter.fromWebContents(webContents) : null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
import com.igalia.wolvic.ui.widgets.AppServicesProvider;
import com.igalia.wolvic.ui.widgets.KeyboardWidget;
import com.igalia.wolvic.ui.widgets.NavigationBarWidget;
import com.igalia.wolvic.ui.widgets.OverlayContentWidget;
import com.igalia.wolvic.ui.widgets.RootWidget;
import com.igalia.wolvic.ui.widgets.TrayWidget;
import com.igalia.wolvic.ui.widgets.UISurfaceTextureRenderer;
Expand Down Expand Up @@ -1107,6 +1108,8 @@ void handleMotionEvent(final int aHandle, final int aDevice, final boolean aFocu
if (!windowWidget.isLibraryVisible()) {
scale = 1.0f;
}
} else if (widget instanceof OverlayContentWidget) {
scale = 1.0f;
}
final float x = aX / scale;
final float y = aY / scale;
Expand Down
23 changes: 23 additions & 0 deletions app/src/common/shared/com/igalia/wolvic/browser/api/WSession.java
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,29 @@ WResult<WSlowScriptResponse> onSlowScript(
*/
@UiThread
default void onShowDynamicToolbar(@NonNull final WSession aSession) {}

public interface OnPaymentHandlerCallback {
void onDismiss();
}

/**
* The view should display its payment handler, overlayed on the active tab.
*
* @param aSession ISession that initiated the callback.
* @param aDisplay IDisplay that initiated the callback.
* @param callback Callback interface.
*/
@UiThread
default void onShowPaymentHandler(@NonNull final WSession aSession,
@NonNull final WDisplay aDisplay,
@NonNull final OnPaymentHandlerCallback callback) {}
/**
* The view should hide its payment handler.
*
* @param aSession ISession that initiated the callback.
*/
@UiThread
default void onHidePaymentHandler(@NonNull final WSession aSession) {}
}

interface NavigationDelegate {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1422,6 +1422,20 @@ public void onExternalResponse(@NonNull WSession aSession, @NonNull WWebResponse
}
}

@Override
public void onShowPaymentHandler(@NonNull final WSession aSession, @NonNull WDisplay aDisplay, @NonNull OnPaymentHandlerCallback callback) {
for (WSession.ContentDelegate listener : mContentListeners) {
listener.onShowPaymentHandler(aSession, aDisplay, callback);
}
}

@Override
public void onHidePaymentHandler(@NonNull final WSession aSession) {
for (WSession.ContentDelegate listener : mContentListeners) {
listener.onHidePaymentHandler(aSession);
}
}

// TextInput Delegate

@Override
Expand Down
Loading

0 comments on commit f225588

Please sign in to comment.