From 57c8969ee8f81d39c86f54cb34bba61a285d1a68 Mon Sep 17 00:00:00 2001 From: Manuel Martin Date: Tue, 29 Oct 2019 22:41:50 +0100 Subject: [PATCH 1/3] Updated Pop-ups blocking flow --- .../vrbrowser/browser/PromptDelegate.java | 204 ++++++++++++------ .../vrbrowser/ui/adapters/PopUpAdapter.java | 6 - .../ui/callbacks/PopUpSiteItemCallback.java | 1 - .../vrbrowser/ui/views/NavigationURLBar.java | 30 ++- .../ui/widgets/NavigationBarWidget.java | 70 +++++- .../vrbrowser/ui/widgets/WindowWidget.java | 35 ++- .../mozilla/vrbrowser/ui/widgets/Windows.java | 7 - .../widgets/dialogs/BaseAppDialogWidget.java | 2 +- .../dialogs/ClearCacheDialogWidget.java | 2 - .../dialogs/PopUpBlockDialogWidget.java | 5 +- .../settings/AllowedPopUpsOptionsView.java | 5 - .../res/drawable/ic_icon_popup_awesomebar.xml | 12 ++ .../main/res/drawable/url_button_start.xml | 25 +++ .../res/drawable/url_button_start_private.xml | 25 +++ app/src/main/res/layout/base_app_dialog.xml | 11 +- app/src/main/res/layout/navigation_url.xml | 78 ++++--- .../main/res/layout/popup_block_dialog.xml | 10 +- app/src/main/res/layout/popup_item.xml | 10 +- app/src/main/res/layout/window_check.xml | 15 -- app/src/main/res/values/dimen.xml | 6 +- app/src/main/res/values/strings.xml | 6 +- app/src/main/res/values/styles.xml | 9 + 22 files changed, 416 insertions(+), 158 deletions(-) create mode 100644 app/src/main/res/drawable/ic_icon_popup_awesomebar.xml create mode 100644 app/src/main/res/drawable/url_button_start.xml create mode 100644 app/src/main/res/drawable/url_button_start_private.xml delete mode 100644 app/src/main/res/layout/window_check.xml diff --git a/app/src/common/shared/org/mozilla/vrbrowser/browser/PromptDelegate.java b/app/src/common/shared/org/mozilla/vrbrowser/browser/PromptDelegate.java index c87e9fc59..3fb09334f 100644 --- a/app/src/common/shared/org/mozilla/vrbrowser/browser/PromptDelegate.java +++ b/app/src/common/shared/org/mozilla/vrbrowser/browser/PromptDelegate.java @@ -2,6 +2,8 @@ import android.app.Application; import android.content.Context; +import android.util.Pair; +import android.util.SparseArray; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -19,7 +21,6 @@ import org.mozilla.vrbrowser.ui.widgets.UIWidget; import org.mozilla.vrbrowser.ui.widgets.WidgetPlacement; import org.mozilla.vrbrowser.ui.widgets.WindowWidget; -import org.mozilla.vrbrowser.ui.widgets.dialogs.BaseAppDialogWidget; import org.mozilla.vrbrowser.ui.widgets.dialogs.PopUpBlockDialogWidget; import org.mozilla.vrbrowser.ui.widgets.prompts.AlertPromptWidget; import org.mozilla.vrbrowser.ui.widgets.prompts.AuthPromptWidget; @@ -31,10 +32,17 @@ import java.util.ArrayList; import java.util.LinkedList; import java.util.List; -import java.util.NoSuchElementException; import java.util.Optional; -public class PromptDelegate implements GeckoSession.PromptDelegate, WindowWidget.WindowListener { +public class PromptDelegate implements + GeckoSession.PromptDelegate, + WindowWidget.WindowListener, + GeckoSession.NavigationDelegate { + + public interface PopUpDelegate { + void onPopUpAvailable(); + void onPopUpsCleared(); + } private PromptWidget mPrompt; private PopUpBlockDialogWidget mPopUpPrompt; @@ -43,6 +51,7 @@ public class PromptDelegate implements GeckoSession.PromptDelegate, WindowWidget private List mAllowedPopUpSites; private PopUpsViewModel mViewModel; private AppExecutors mExecutors; + private PopUpDelegate mPopupDelegate; public PromptDelegate(@NonNull Context context) { mContext = context; @@ -59,16 +68,55 @@ public void attachToWindow(@NonNull WindowWidget window) { mAttachedWindow = window; mAttachedWindow.addWindowListener(this); - mAttachedWindow.getSession().setPromptDelegate(this); mViewModel.getAll().observeForever(mObserver); + + if (getSession() != null) { + setUpSession(getSession()); + } } public void detachFromWindow() { + if (getSession() != null) { + cleanSession(getSession()); + } + if (mAttachedWindow != null) { mAttachedWindow.removeWindowListener(this); mAttachedWindow = null; } mViewModel.getAll().removeObserver(mObserver); + + clearPopUps(); + } + + private Session getSession() { + if (mAttachedWindow != null) { + return mAttachedWindow.getSession(); + } + return null; + } + + private void setUpSession(@NonNull Session aSession) { + aSession.setPromptDelegate(this); + aSession.addNavigationListener(this); + } + + private void cleanSession(@NonNull Session aSession) { + aSession.setPromptDelegate(null); + aSession.removeNavigationListener(this); + mPopUpRequests.remove(aSession.hashCode()); + } + + public void setPopupDelegate(@Nullable PopUpDelegate delegate) { + mPopupDelegate = delegate; + } + + public void clearPopUps() { + mPopUpRequests.clear(); + + if (mPopupDelegate != null) { + mPopupDelegate.onPopUpsCleared(); + } } @Nullable @@ -220,10 +268,34 @@ public GeckoResult onPopupPrompt(@NonNull GeckoSession geckoSess if (!SettingsStore.getInstance(mContext).isPopUpsBlockingEnabled()) { result.complete(popupPrompt.confirm(AllowOrDeny.ALLOW)); + } else { - String uri = mAttachedWindow.getSession().getCurrentUri(); - PopUpRequest request = PopUpRequest.newRequest(uri, popupPrompt, result); - handlePopUpRequest(request); + final int sessionId = geckoSession.hashCode(); + final String uri = mAttachedWindow.getSession().getCurrentUri(); + + Optional site = mAllowedPopUpSites.stream().filter((item) -> item.url.equals(uri)).findFirst(); + if (site.isPresent()) { + if (site.get().allowed) { + result.complete(popupPrompt.confirm(AllowOrDeny.ALLOW)); + + } else { + result.complete(popupPrompt.dismiss()); + } + + } else { + PopUpRequest request = PopUpRequest.newRequest(popupPrompt, result, sessionId); + Pair> domainRequestList = mPopUpRequests.get(sessionId); + if (domainRequestList == null) { + LinkedList requestList = new LinkedList<>(); + domainRequestList = new Pair<>(uri, requestList); + mPopUpRequests.put(sessionId, domainRequestList); + } + domainRequestList.second.add(request); + + if (mPopupDelegate != null) { + mPopupDelegate.onPopUpAvailable(); + } + } } return result; @@ -231,84 +303,87 @@ public GeckoResult onPopupPrompt(@NonNull GeckoSession geckoSess static class PopUpRequest { - public static PopUpRequest newRequest(@NonNull String uri, @NonNull PopupPrompt prompt, @NonNull GeckoResult response) { + public static PopUpRequest newRequest(@NonNull PopupPrompt prompt, @NonNull GeckoResult response, int sessionId) { PopUpRequest request = new PopUpRequest(); - request.uri = uri; request.prompt = prompt; request.response = response; + request.sessionId = sessionId; return request; } - String uri; PopupPrompt prompt; GeckoResult response; + int sessionId; } - private LinkedList mPopUpRequests = new LinkedList<>(); - - private void handlePopUpRequest(@NonNull PopUpRequest request) { - if (mPopUpPrompt != null && mPopUpPrompt.isVisible()) { - mPopUpRequests.add(request); + private SparseArray>> mPopUpRequests = new SparseArray<>(); - } else { - Optional site = mAllowedPopUpSites.stream().filter((item) -> item.url.equals(request.uri)).findFirst(); - if (!site.isPresent()) { - mPopUpPrompt = new PopUpBlockDialogWidget(mContext); - mPopUpPrompt.getPlacement().parentHandle = mAttachedWindow.getHandle(); - mPopUpPrompt.getPlacement().parentAnchorY = 0.0f; - mPopUpPrompt.getPlacement().translationY = WidgetPlacement.unitFromMeters(mContext, R.dimen.base_app_dialog_y_distance); - mPopUpPrompt.setTitle(request.uri); - mPopUpPrompt.setButtonsDelegate(new BaseAppDialogWidget.Delegate() { - @Override - public void onButtonClicked(int index) { - boolean allowed = index != PopUpBlockDialogWidget.NEGATIVE; - boolean askAgain = mPopUpPrompt.askAgain(); - if (!askAgain) { - mAllowedPopUpSites.add(new PopUpSite(request.uri, allowed)); - mViewModel.insertSite(request.uri, allowed); - } + public void showPopUps(GeckoSession session) { + Pair> requests = mPopUpRequests.get(session.hashCode()); + if (requests != null && !requests.second.isEmpty()) { + showPopUp(session.hashCode(), requests); + } + } - if (allowed) { - request.response.complete(request.prompt.confirm(AllowOrDeny.ALLOW)); + public boolean hasPendingPopUps(GeckoSession session) { + Pair> requests = mPopUpRequests.get(session.hashCode()); + if (requests != null) { + return !requests.second.isEmpty(); + } - } else { - request.response.complete(request.prompt.dismiss()); - } + return false; + } - mExecutors.mainThread().execute(() -> { - try { - PopUpRequest next = mPopUpRequests.pop(); - handlePopUpRequest(next); + private void showPopUp(int sessionId, @NonNull Pair> requests) { + String uri = requests.first; + Optional site = mAllowedPopUpSites.stream().filter((item) -> item.url.equals(uri)).findFirst(); + if (!site.isPresent()) { + mPopUpPrompt = new PopUpBlockDialogWidget(mContext); + mPopUpPrompt.getPlacement().parentHandle = mAttachedWindow.getHandle(); + mPopUpPrompt.getPlacement().parentAnchorY = 0.0f; + mPopUpPrompt.getPlacement().translationY = WidgetPlacement.unitFromMeters(mContext, R.dimen.base_app_dialog_y_distance); + mPopUpPrompt.setTitle(uri); + mPopUpPrompt.setButtonsDelegate(index -> { + boolean allowed = index != PopUpBlockDialogWidget.NEGATIVE; + boolean askAgain = mPopUpPrompt.askAgain(); + if (allowed && !askAgain) { + mAllowedPopUpSites.add(new PopUpSite(uri, allowed)); + mViewModel.insertSite(uri, allowed); + } - } catch (NoSuchElementException ignored) {} - }); - } + if (allowed) { + requests.second.forEach((request) -> { + request.response.complete(request.prompt.confirm(AllowOrDeny.ALLOW)); + }); - @Override - public void onDismiss() { - request.response.complete(request.prompt.dismiss()); + mPopUpRequests.remove(sessionId); - mExecutors.mainThread().execute(() -> { - try { - PopUpRequest next = mPopUpRequests.pop(); - handlePopUpRequest(next); + mExecutors.mainThread().execute(() -> { + if (mPopupDelegate != null) { + mPopupDelegate.onPopUpsCleared(); + } + }); - } catch (NoSuchElementException ignored) {} - }); - } - }); - mPopUpPrompt.show(UIWidget.REQUEST_FOCUS); + } else { + mExecutors.mainThread().execute(() -> { + if (mPopupDelegate != null) { + mPopupDelegate.onPopUpAvailable(); + } + }); + } + }); + mPopUpPrompt.show(UIWidget.REQUEST_FOCUS); - } else { + } else { + requests.second.forEach((request) -> { if (site.get().allowed) { request.response.complete(request.prompt.confirm(AllowOrDeny.ALLOW)); } else { request.response.complete(request.prompt.dismiss()); } - } - + }); } } @@ -316,7 +391,14 @@ public void onDismiss() { @Override public void onSessionChanged(@NonNull Session aOldSession, @NonNull Session aSession) { - aOldSession.setPromptDelegate(null); - aSession.setPromptDelegate(this); + cleanSession(aOldSession); + setUpSession(aSession); + } + + // NavigationDelegate + + @Override + public void onLocationChange(@NonNull GeckoSession geckoSession, @Nullable String s) { + clearPopUps(); } } diff --git a/app/src/common/shared/org/mozilla/vrbrowser/ui/adapters/PopUpAdapter.java b/app/src/common/shared/org/mozilla/vrbrowser/ui/adapters/PopUpAdapter.java index b02f6e537..888ab4661 100644 --- a/app/src/common/shared/org/mozilla/vrbrowser/ui/adapters/PopUpAdapter.java +++ b/app/src/common/shared/org/mozilla/vrbrowser/ui/adapters/PopUpAdapter.java @@ -93,11 +93,6 @@ public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int return false; }); - binding.site.setOnCheckedChangeListener((compoundButton, value, apply) -> { - if (mCallback != null) { - mCallback.onSwitch(binding.getItem(), value); - } - }); return new PopUpSiteViewHolder(binding); } @@ -107,7 +102,6 @@ public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int positi PopUpSiteViewHolder siteHolder = (PopUpSiteViewHolder) holder; PopUpSite site = mDisplayList.get(position); siteHolder.binding.setItem(site); - siteHolder.binding.site.setChecked(site.allowed); } @Override diff --git a/app/src/common/shared/org/mozilla/vrbrowser/ui/callbacks/PopUpSiteItemCallback.java b/app/src/common/shared/org/mozilla/vrbrowser/ui/callbacks/PopUpSiteItemCallback.java index 60f0612d0..350bfe96b 100644 --- a/app/src/common/shared/org/mozilla/vrbrowser/ui/callbacks/PopUpSiteItemCallback.java +++ b/app/src/common/shared/org/mozilla/vrbrowser/ui/callbacks/PopUpSiteItemCallback.java @@ -6,5 +6,4 @@ public interface PopUpSiteItemCallback { void onDelete(@NonNull PopUpSite item); - void onSwitch(@NonNull PopUpSite item, boolean value); } diff --git a/app/src/common/shared/org/mozilla/vrbrowser/ui/views/NavigationURLBar.java b/app/src/common/shared/org/mozilla/vrbrowser/ui/views/NavigationURLBar.java index ef9ae55d0..9122e0279 100644 --- a/app/src/common/shared/org/mozilla/vrbrowser/ui/views/NavigationURLBar.java +++ b/app/src/common/shared/org/mozilla/vrbrowser/ui/views/NavigationURLBar.java @@ -94,9 +94,10 @@ private Unit domainAutocompleteFilter(String text) { public interface NavigationURLBarDelegate { void onVoiceSearchClicked(); - void onShowSearchPopup(); - void onHideSearchPopup(); + void onShowAwesomeBar(); + void onHideAwesomeBar(); void onLongPress(float centerX, SelectionActionWidget actionMenu); + void onPopUpButtonClicked(); } public NavigationURLBar(Context context, AttributeSet attrs) { @@ -221,6 +222,8 @@ private void initialize(Context aContext) { mBinding.clearButton.setTag(R.string.view_id_tag, R.id.clearButton); mBinding.clearButton.setOnClickListener(mClearListener); + mBinding.popup.setOnClickListener(mPopUpListener); + mLoadingAnimation = AnimationUtils.loadAnimation(aContext, R.anim.loading); TypedValue typedValue = new TypedValue(); @@ -241,6 +244,7 @@ private void initialize(Context aContext) { mBinding.setIsFocused(false); mBinding.setIsSpecialUrl(false); mBinding.setIsUrlEmpty(true); + mBinding.setIsPopUpAvailable(false); mBinding.executePendingBindings(); clearFocus(); @@ -401,6 +405,14 @@ public void setPrivateMode(boolean isEnabled) { mBinding.setIsPrivateMode(isEnabled); } + public void setIsPopUpAvailable(boolean isAvailable) { + mBinding.setIsPopUpAvailable(isAvailable); + } + + public UIButton getPopUpButton() { + return mBinding.popup; + } + public void handleURLEdit(String text) { text = text.trim(); URI uri = null; @@ -438,7 +450,7 @@ public void handleURLEdit(String text) { mSession.loadUri(url); if (mDelegate != null) { - mDelegate.onHideSearchPopup(); + mDelegate.onHideAwesomeBar(); } } @@ -472,6 +484,16 @@ public void setClickable(boolean clickable) { mBinding.urlEditText.getText().clear(); }; + private OnClickListener mPopUpListener = view -> { + if (mAudio != null) { + mAudio.playSound(AudioEngine.Sound.CLICK); + } + + if (mDelegate != null) { + mDelegate.onPopUpButtonClicked(); + } + }; + private TextWatcher mURLTextWatcher = new TextWatcher() { @Override public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { @@ -489,7 +511,7 @@ public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { @Override public void afterTextChanged(Editable editable) { if (mDelegate != null && mBinding.urlEditText.isFocused()) { - mDelegate.onShowSearchPopup(); + mDelegate.onShowAwesomeBar(); } hideSelectionMenu(); } diff --git a/app/src/common/shared/org/mozilla/vrbrowser/ui/widgets/NavigationBarWidget.java b/app/src/common/shared/org/mozilla/vrbrowser/ui/widgets/NavigationBarWidget.java index cc53efb1a..1fed734f8 100644 --- a/app/src/common/shared/org/mozilla/vrbrowser/ui/widgets/NavigationBarWidget.java +++ b/app/src/common/shared/org/mozilla/vrbrowser/ui/widgets/NavigationBarWidget.java @@ -27,6 +27,7 @@ import org.mozilla.vrbrowser.R; import org.mozilla.vrbrowser.audio.AudioEngine; import org.mozilla.vrbrowser.browser.Media; +import org.mozilla.vrbrowser.browser.PromptDelegate; import org.mozilla.vrbrowser.browser.SessionChangeListener; import org.mozilla.vrbrowser.browser.SettingsStore; import org.mozilla.vrbrowser.browser.engine.Session; @@ -57,6 +58,8 @@ public class NavigationBarWidget extends UIWidget implements GeckoSession.Naviga SharedPreferences.OnSharedPreferenceChangeListener, SuggestionsWidget.URLBarPopupDelegate, WindowWidget.BookmarksViewDelegate, WindowWidget.HistoryViewDelegate, TrayListener, WindowWidget.WindowListener { + private static final int NOTIFICATION_DURATION = 3000; + private AudioEngine mAudio; private UIButton mBackButton; private UIButton mForwardButton; @@ -99,6 +102,7 @@ public class NavigationBarWidget extends UIWidget implements GeckoSession.Naviga private @VideoProjectionMenuWidget.VideoProjectionFlags Integer mAutoSelectedProjection; private HamburgerMenuWidget mHamburgerMenu; private SendTabDialogWidget mSendTabDialog; + private TooltipWidget mPopUpNotification; public NavigationBarWidget(Context aContext) { super(aContext); @@ -385,6 +389,8 @@ protected void initializeWidgetPlacement(WidgetPlacement aPlacement) { @Override public void detachFromWindow() { + hideNotification(mURLBar.getPopUpButton()); + if (mAttachedWindow != null && mAttachedWindow.isResizing()) { exitResizeMode(ResizeAction.RESTORE_SIZE); } @@ -399,6 +405,7 @@ public void detachFromWindow() { mAttachedWindow.removeBookmarksViewListener(this); mAttachedWindow.removeHistoryViewListener(this); mAttachedWindow.removeWindowListener(this); + mAttachedWindow.setPopUpDelegate(null); } mAttachedWindow = null; } @@ -415,6 +422,7 @@ public void attachToWindow(@NonNull WindowWidget aWindow) { mAttachedWindow.addBookmarksViewListener(this); mAttachedWindow.addHistoryViewListener(this); mAttachedWindow.addWindowListener(this); + mAttachedWindow.setPopUpDelegate(mPopUpDelegate); if (mAttachedWindow != null) { mURLBar.setIsLibraryVisible(mAttachedWindow.isBookmarksVisible() || mAttachedWindow.isHistoryVisible()); @@ -432,6 +440,7 @@ public void attachToWindow(@NonNull WindowWidget aWindow) { mURLBar.setHint(R.string.search_placeholder); mURLBar.setIsLibraryVisible(false); } + mURLBar.setIsPopUpAvailable(mAttachedWindow.hasPendingPopUps()); } clearFocus(); @@ -468,6 +477,8 @@ private void cleanSession(@NonNull Session aSession) { @Override public void onSessionChanged(@NonNull Session aOldSession, @NonNull Session aSession) { + mURLBar.setIsPopUpAvailable(mAttachedWindow.hasPendingPopUps()); + cleanSession(aOldSession); setUpSession(aSession); } @@ -915,7 +926,7 @@ public void onVoiceSearchClicked() { @Override - public void onShowSearchPopup() { + public void onShowAwesomeBar() { if (mAwesomeBar == null) { mAwesomeBar = createChild(SuggestionsWidget.class); mAwesomeBar.setURLBarPopupDelegate(this); @@ -949,7 +960,7 @@ public void onShowSearchPopup() { } @Override - public void onHideSearchPopup() { + public void onHideAwesomeBar() { if (mAwesomeBar != null) { mAwesomeBar.hide(UIWidget.KEEP_WIDGET); } @@ -967,6 +978,11 @@ public void onLongPress(float centerX, SelectionActionWidget actionMenu) { actionMenu.getPlacement().parentAnchorX = x / getMeasuredWidth(); } + @Override + public void onPopUpButtonClicked() { + mAttachedWindow.showPopUps(); + } + // VoiceSearch Delegate @Override @@ -1161,4 +1177,54 @@ public void showSendTabDialog() { }); mSendTabDialog.show(REQUEST_FOCUS); } + + private PromptDelegate.PopUpDelegate mPopUpDelegate = new PromptDelegate.PopUpDelegate() { + @Override + public void onPopUpAvailable() { + showPopUpsBlockedNotification(); + mURLBar.setIsPopUpAvailable(true); + } + + @Override + public void onPopUpsCleared() { + mURLBar.setIsPopUpAvailable(false); + } + }; + + public void showPopUpsBlockedNotification() { + post(() -> showNotification(mURLBar.getPopUpButton(), R.string.popup_tooltip)); + } + + private void showNotification(UIButton button, int stringRes) { + if (mPopUpNotification != null && mPopUpNotification.isVisible()) { + return; + } + + Rect offsetViewBounds = new Rect(); + getDrawingRect(offsetViewBounds); + offsetDescendantRectToMyCoords(button, offsetViewBounds); + + float ratio = WidgetPlacement.viewToWidgetRatio(getContext(), NavigationBarWidget.this); + + mPopUpNotification = new TooltipWidget(getContext(), R.layout.library_notification); + mPopUpNotification.getPlacement().parentHandle = getHandle(); + mPopUpNotification.getPlacement().anchorY = 0.0f; + mPopUpNotification.getPlacement().translationX = (offsetViewBounds.left + button.getWidth() / 2.0f) * ratio; + mPopUpNotification.getPlacement().translationY = ((offsetViewBounds.top - 60) * ratio); + mPopUpNotification.getPlacement().translationZ = 25.0f; + mPopUpNotification.getPlacement().density = WidgetPlacement.floatDimension(getContext(), R.dimen.tooltip_default_density); + mPopUpNotification.setText(stringRes); + mPopUpNotification.setCurvedMode(false); + mPopUpNotification.show(UIWidget.CLEAR_FOCUS); + + postDelayed(() -> hideNotification(button), NOTIFICATION_DURATION); + } + + private void hideNotification(UIButton button) { + if (mPopUpNotification != null) { + mPopUpNotification.hide(UIWidget.REMOVE_WIDGET); + mPopUpNotification = null; + } + button.setNotificationMode(false); + } } diff --git a/app/src/common/shared/org/mozilla/vrbrowser/ui/widgets/WindowWidget.java b/app/src/common/shared/org/mozilla/vrbrowser/ui/widgets/WindowWidget.java index f71c467a3..a7be62f2f 100644 --- a/app/src/common/shared/org/mozilla/vrbrowser/ui/widgets/WindowWidget.java +++ b/app/src/common/shared/org/mozilla/vrbrowser/ui/widgets/WindowWidget.java @@ -8,7 +8,6 @@ import android.content.Context; import android.graphics.Canvas; import android.graphics.Matrix; -import android.graphics.Point; import android.graphics.PointF; import android.graphics.Rect; import android.graphics.SurfaceTexture; @@ -35,6 +34,7 @@ import org.mozilla.geckoview.PanZoomController; import org.mozilla.vrbrowser.R; import org.mozilla.vrbrowser.browser.HistoryStore; +import org.mozilla.vrbrowser.browser.PromptDelegate; import org.mozilla.vrbrowser.browser.SessionChangeListener; import org.mozilla.vrbrowser.browser.SettingsStore; import org.mozilla.vrbrowser.browser.VideoAvailabilityListener; @@ -65,6 +65,7 @@ import java.util.Arrays; import java.util.Calendar; import java.util.GregorianCalendar; +import java.util.concurrent.CopyOnWriteArrayList; import mozilla.components.concept.storage.PageObservation; import mozilla.components.concept.storage.PageVisit; @@ -111,7 +112,6 @@ default void onBookmarksHidden(WindowWidget aWindow) {} private Runnable mFirstDrawCallback; private boolean mIsInVRVideoMode; private View mView; - private Point mLastMouseClickPos; private Session mSession; private int mWindowId; private BookmarksView mBookmarksView; @@ -122,7 +122,7 @@ default void onBookmarksHidden(WindowWidget aWindow) {} private Windows.WindowPlacement mWindowPlacementBeforeFullscreen = Windows.WindowPlacement.FRONT; private float mMaxWindowScale = 3; private boolean mIsRestored = false; - private ArrayList mListeners; + private CopyOnWriteArrayList mListeners; boolean mActive = false; boolean mHovered = false; boolean mClickedAfterFocus = false; @@ -134,7 +134,7 @@ default void onBookmarksHidden(WindowWidget aWindow) {} private boolean mIsFullScreen; private boolean mAfterFirstPaint; private boolean mCaptureOnPageStop; - private View mSendTabCheckLayout; + private PromptDelegate mPromptDelegate; public interface WindowListener { default void onFocusRequest(@NonNull WindowWidget aWindow) {} @@ -159,7 +159,8 @@ public WindowWidget(Context aContext, int windowId, Session aSession) { private void initialize(Context aContext) { mWidgetManager = (WidgetManagerDelegate) aContext; mBorderWidth = SettingsStore.getInstance(aContext).getTransparentBorderWidth(); - mListeners = new ArrayList<>(); + + mListeners = new CopyOnWriteArrayList<>(); setupListeners(mSession); mBookmarksView = new BookmarksView(aContext); @@ -189,8 +190,8 @@ private void initialize(Context aContext) { mTitleBar = new TitleBarWidget(aContext); mTitleBar.attachToWindow(this); - // Load the send tab check layout that is displayed after a tab is sent - mSendTabCheckLayout = inflate(getContext(), R.layout.window_check, null); + mPromptDelegate = new PromptDelegate(getContext()); + mPromptDelegate.attachToWindow(this); setFocusable(true); @@ -216,6 +217,10 @@ protected void initializeWidgetPlacement(WidgetPlacement aPlacement) { // Check Windows.placeWindow method for remaining placement set-up } + public void setPopUpDelegate(@Nullable PromptDelegate.PopUpDelegate delegate) { + mPromptDelegate.setPopupDelegate(delegate); + } + void setupListeners(Session aSession) { aSession.addSessionChangeListener(this); aSession.addContentListener(this); @@ -935,6 +940,7 @@ public void releaseWidget() { } mBookmarksView.removeBookmarksListener(mBookmarksListener); mHistoryView.removeHistoryListener(mHistoryListener); + mPromptDelegate.detachFromWindow(); super.releaseWidget(); } @@ -1030,6 +1036,20 @@ public void releaseDisplay(GeckoSession aSession) { } } + public void showPopUps() { + if (mPromptDelegate != null) { + mPromptDelegate.showPopUps(getSession().getGeckoSession()); + } + } + + public boolean hasPendingPopUps() { + if (mPromptDelegate != null) { + return mPromptDelegate.hasPendingPopUps(getSession().getGeckoSession()); + } + + return false; + } + // Session.GeckoSessionChange @Override public void onCurrentSessionChange(GeckoSession aOldSession, GeckoSession aSession) { @@ -1602,4 +1622,5 @@ public void onDismiss() { public void onHideAction(@NonNull GeckoSession aSession, int aHideReason) { hideContextMenus(); } + } diff --git a/app/src/common/shared/org/mozilla/vrbrowser/ui/widgets/Windows.java b/app/src/common/shared/org/mozilla/vrbrowser/ui/widgets/Windows.java index cd6d53eea..c1904e80c 100644 --- a/app/src/common/shared/org/mozilla/vrbrowser/ui/widgets/Windows.java +++ b/app/src/common/shared/org/mozilla/vrbrowser/ui/widgets/Windows.java @@ -16,7 +16,6 @@ import org.mozilla.vrbrowser.VRBrowserApplication; import org.mozilla.vrbrowser.browser.Accounts; import org.mozilla.vrbrowser.browser.Media; -import org.mozilla.vrbrowser.browser.PromptDelegate; import org.mozilla.vrbrowser.browser.Services; import org.mozilla.vrbrowser.browser.SettingsStore; import org.mozilla.vrbrowser.browser.engine.Session; @@ -101,7 +100,6 @@ class WindowsState { private boolean mStoredCurvedMode = false; private boolean mForcedCurvedMode = false; private boolean mIsPaused = false; - private PromptDelegate mPromptDelegate; private TabsWidget mTabsWidget; private Accounts mAccounts; private Services mServices; @@ -136,8 +134,6 @@ public Windows(Context aContext) { mRegularWindowPlacement = WindowPlacement.FRONT; mPrivateWindowPlacement = WindowPlacement.FRONT; - mPromptDelegate = new PromptDelegate(mContext); - mStoredCurvedMode = SettingsStore.getInstance(mContext).getCylinderDensity() > 0.0f; mAccounts = ((VRBrowserApplication)mContext.getApplicationContext()).getAccounts(); @@ -386,8 +382,6 @@ public void focusWindow(@NonNull WindowWidget aWindow) { if (mDelegate != null) { mDelegate.onFocusedWindowChanged(mFocusedWindow, prev); } - - mPromptDelegate.attachToWindow(mFocusedWindow); } } @@ -434,7 +428,6 @@ public void onResume() { public void onDestroy() { mDelegate = null; - mPromptDelegate.detachFromWindow(); for (WindowWidget window: mRegularWindows) { window.close(); } diff --git a/app/src/common/shared/org/mozilla/vrbrowser/ui/widgets/dialogs/BaseAppDialogWidget.java b/app/src/common/shared/org/mozilla/vrbrowser/ui/widgets/dialogs/BaseAppDialogWidget.java index c65f6c407..0135f9784 100644 --- a/app/src/common/shared/org/mozilla/vrbrowser/ui/widgets/dialogs/BaseAppDialogWidget.java +++ b/app/src/common/shared/org/mozilla/vrbrowser/ui/widgets/dialogs/BaseAppDialogWidget.java @@ -66,7 +66,7 @@ protected void initialize(Context aContext) { protected void initializeWidgetPlacement(WidgetPlacement aPlacement) { aPlacement.visible = false; aPlacement.width = WidgetPlacement.dpDimension(getContext(), R.dimen.base_app_dialog_width); - aPlacement.height = WidgetPlacement.pixelDimension(getContext(), R.dimen.browser_width_pixels)/2; + aPlacement.height = WidgetPlacement.dpDimension(getContext(), R.dimen.base_app_dialog_height); aPlacement.parentAnchorX = 0.5f; aPlacement.parentAnchorY = 0.5f; aPlacement.anchorX = 0.5f; diff --git a/app/src/common/shared/org/mozilla/vrbrowser/ui/widgets/dialogs/ClearCacheDialogWidget.java b/app/src/common/shared/org/mozilla/vrbrowser/ui/widgets/dialogs/ClearCacheDialogWidget.java index 8f9e06f95..f2828dec3 100644 --- a/app/src/common/shared/org/mozilla/vrbrowser/ui/widgets/dialogs/ClearCacheDialogWidget.java +++ b/app/src/common/shared/org/mozilla/vrbrowser/ui/widgets/dialogs/ClearCacheDialogWidget.java @@ -39,8 +39,6 @@ protected void initialize(Context aContext) { // Inflate this data binding layout mClearCacheBinding = DataBindingUtil.inflate(inflater, R.layout.clear_cache_dialog, mBinding.dialogContent, true); mClearCacheBinding.clearCacheRadio.setChecked(0, false); - - mWidgetPlacement.width = WidgetPlacement.dpDimension(getContext(), R.dimen.cache_app_dialog_width); } public @ClearCacheRange int getSelectedRange() { diff --git a/app/src/common/shared/org/mozilla/vrbrowser/ui/widgets/dialogs/PopUpBlockDialogWidget.java b/app/src/common/shared/org/mozilla/vrbrowser/ui/widgets/dialogs/PopUpBlockDialogWidget.java index 58b0be6ee..a7574dc6e 100644 --- a/app/src/common/shared/org/mozilla/vrbrowser/ui/widgets/dialogs/PopUpBlockDialogWidget.java +++ b/app/src/common/shared/org/mozilla/vrbrowser/ui/widgets/dialogs/PopUpBlockDialogWidget.java @@ -12,7 +12,6 @@ import org.mozilla.vrbrowser.R; import org.mozilla.vrbrowser.databinding.PopupBlockDialogBinding; -import org.mozilla.vrbrowser.ui.widgets.WidgetPlacement; public class PopUpBlockDialogWidget extends BaseAppDialogWidget { @@ -33,10 +32,8 @@ protected void initialize(Context aContext) { mPopUpBinding = DataBindingUtil.inflate(inflater, R.layout.popup_block_dialog, mBinding.dialogContent, true); mPopUpBinding.contentCheckbox.setOnCheckedChangeListener((buttonView, isChecked) -> mIsChecked = isChecked); - mWidgetPlacement.width = WidgetPlacement.dpDimension(getContext(), R.dimen.pop_up_app_dialog_width); - setButtons(new int[] { - R.string.popup_block_button_do_not_show, + R.string.popup_block_button_cancel, R.string.popup_block_button_show }); diff --git a/app/src/common/shared/org/mozilla/vrbrowser/ui/widgets/settings/AllowedPopUpsOptionsView.java b/app/src/common/shared/org/mozilla/vrbrowser/ui/widgets/settings/AllowedPopUpsOptionsView.java index f112298da..27063d9a1 100644 --- a/app/src/common/shared/org/mozilla/vrbrowser/ui/widgets/settings/AllowedPopUpsOptionsView.java +++ b/app/src/common/shared/org/mozilla/vrbrowser/ui/widgets/settings/AllowedPopUpsOptionsView.java @@ -107,10 +107,5 @@ public void onDelete(@NonNull PopUpSite item) { mViewModel.deleteSite(item); } - @Override - public void onSwitch(@NonNull PopUpSite item, boolean on) { - item.allowed = on; - mViewModel.insertSite(item); - } }; } diff --git a/app/src/main/res/drawable/ic_icon_popup_awesomebar.xml b/app/src/main/res/drawable/ic_icon_popup_awesomebar.xml new file mode 100644 index 000000000..7da3a06aa --- /dev/null +++ b/app/src/main/res/drawable/ic_icon_popup_awesomebar.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/url_button_start.xml b/app/src/main/res/drawable/url_button_start.xml new file mode 100644 index 000000000..e70e59d92 --- /dev/null +++ b/app/src/main/res/drawable/url_button_start.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/url_button_start_private.xml b/app/src/main/res/drawable/url_button_start_private.xml new file mode 100644 index 000000000..eb3d6aaaa --- /dev/null +++ b/app/src/main/res/drawable/url_button_start_private.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/base_app_dialog.xml b/app/src/main/res/layout/base_app_dialog.xml index 5bc7165d2..bf1c4e30d 100644 --- a/app/src/main/res/layout/base_app_dialog.xml +++ b/app/src/main/res/layout/base_app_dialog.xml @@ -4,8 +4,8 @@ diff --git a/app/src/main/res/layout/navigation_url.xml b/app/src/main/res/layout/navigation_url.xml index f7401163b..6cc32458d 100644 --- a/app/src/main/res/layout/navigation_url.xml +++ b/app/src/main/res/layout/navigation_url.xml @@ -47,6 +47,10 @@ + + + android:foreground="@{isPrivateMode ? @drawable/url_background_private_outline : @drawable/url_background_outline}"> - - - + + + + + + + + + + + @@ -140,9 +170,9 @@ android:id="@+id/urlEditText" android:layout_width="match_parent" android:layout_height="match_parent" - android:paddingStart="5dp" + android:paddingStart="10dp" android:paddingEnd="10dp" - android:layout_toStartOf="@id/buttonsLayout" + android:layout_toStartOf="@id/endButtonsLayout" android:layout_toEndOf="@id/iconsLayout" android:foreground="@{isUrlEmpty ? @drawable/url_bar_hint_fading_edge : null}" android:foregroundGravity="fill_vertical|right" diff --git a/app/src/main/res/layout/popup_block_dialog.xml b/app/src/main/res/layout/popup_block_dialog.xml index 9abefce62..6dd7a6a8f 100644 --- a/app/src/main/res/layout/popup_block_dialog.xml +++ b/app/src/main/res/layout/popup_block_dialog.xml @@ -4,15 +4,16 @@ + android:layout_height="match_parent" + android:layout_marginStart="40dp" + android:layout_marginEnd="40dp" + android:gravity="center"> diff --git a/app/src/main/res/layout/popup_item.xml b/app/src/main/res/layout/popup_item.xml index 285020c23..48eb497cf 100644 --- a/app/src/main/res/layout/popup_item.xml +++ b/app/src/main/res/layout/popup_item.xml @@ -34,8 +34,9 @@ android:focusable="true" android:onClick="@{(view) -> callback != null ? callback.onDelete(item) : void}" /> - + android:singleLine="true" + android:text="@{item.url}" + tool:text="Site" /> diff --git a/app/src/main/res/layout/window_check.xml b/app/src/main/res/layout/window_check.xml deleted file mode 100644 index bfc22e778..000000000 --- a/app/src/main/res/layout/window_check.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - diff --git a/app/src/main/res/values/dimen.xml b/app/src/main/res/values/dimen.xml index a9f104881..06c7aff31 100644 --- a/app/src/main/res/values/dimen.xml +++ b/app/src/main/res/values/dimen.xml @@ -16,6 +16,7 @@ 720dp 44dp 28dp + 36dp 36dp @@ -279,7 +280,8 @@ 420dp - 420dp + 450dp + 340dp 2 1.2 @@ -287,8 +289,6 @@ 585dp - 420dp - 280dp 120dp 10dp diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 46ebe8b1f..214c34af6 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -983,6 +983,10 @@ browser's navigation bar. The button it labels, when pressed, clears the navigation bar text. --> Clear + + Pop-Up Blocked + Show site info. @@ -1175,7 +1179,7 @@ - Don’t show + Cancel diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 3e3eb1a7d..5c0fee385 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -190,6 +190,15 @@ center + +