Commit 5767abca authored by Mugdha Lakhani's avatar Mugdha Lakhani Committed by Commit Bot

[WebLayer] Move Offline code into Delegate.

Offline Pages isn't a feature WebLayer intends to support for now.
Move offline pages related logic from PageInfoController to
ChromePageInfoControllerDelegate so that the former can be
componentized.

Bug: 1052375
Change-Id: I59fc6208a5ce3528c6d0e59da3733679d63ea894
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2144029
Commit-Queue: Mugdha Lakhani <nator@chromium.org>
Reviewed-by: default avatarTheresa  <twellington@chromium.org>
Reviewed-by: default avatarCarlos Knippschild <carlosk@chromium.org>
Reviewed-by: default avatarPeter Conn <peconn@chromium.org>
Reviewed-by: default avatarColin Blundell <blundell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#759629}
parent f5046291
...@@ -569,9 +569,9 @@ public class VrShell extends GvrLayout ...@@ -569,9 +569,9 @@ public class VrShell extends GvrLayout
WebContents webContents = tab.getWebContents(); WebContents webContents = tab.getWebContents();
PageInfoController.show(mActivity, webContents, null, PageInfoController.show(mActivity, webContents, null,
PageInfoController.OpenedFromSource.VR, PageInfoController.OpenedFromSource.VR,
/*offlinePageLoadUrlDelegate=*/ new ChromePageInfoControllerDelegate(mActivity, webContents,
new OfflinePageUtils.TabOfflinePageLoadUrlDelegate(tab), /*offlinePageLoadUrlDelegate=*/
new ChromePageInfoControllerDelegate(mActivity, webContents)); new OfflinePageUtils.TabOfflinePageLoadUrlDelegate(tab)));
} }
// Called because showing audio permission dialog isn't supported in VR. This happens when // Called because showing audio permission dialog isn't supported in VR. This happens when
......
...@@ -1987,9 +1987,9 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent> ...@@ -1987,9 +1987,9 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent>
WebContents webContents = currentTab.getWebContents(); WebContents webContents = currentTab.getWebContents();
PageInfoController.show(this, webContents, null, PageInfoController.show(this, webContents, null,
PageInfoController.OpenedFromSource.MENU, PageInfoController.OpenedFromSource.MENU,
/*offlinePageLoadUrlDelegate=*/ new ChromePageInfoControllerDelegate(this, webContents,
new OfflinePageUtils.TabOfflinePageLoadUrlDelegate(currentTab), /*offlinePageLoadUrlDelegate=*/
new ChromePageInfoControllerDelegate(this, webContents)); new OfflinePageUtils.TabOfflinePageLoadUrlDelegate(currentTab)));
} else if (id == R.id.translate_id) { } else if (id == R.id.translate_id) {
RecordUserAction.record("MobileMenuTranslate"); RecordUserAction.record("MobileMenuTranslate");
Tracker tracker = TrackerFactory.getTrackerForProfile( Tracker tracker = TrackerFactory.getTrackerForProfile(
......
...@@ -250,9 +250,9 @@ public class CustomTabActivity extends BaseCustomTabActivity<CustomTabActivityCo ...@@ -250,9 +250,9 @@ public class CustomTabActivity extends BaseCustomTabActivity<CustomTabActivityCo
WebContents webContents = tab.getWebContents(); WebContents webContents = tab.getWebContents();
PageInfoController.show(this, webContents, getToolbarManager().getContentPublisher(), PageInfoController.show(this, webContents, getToolbarManager().getContentPublisher(),
PageInfoController.OpenedFromSource.MENU, PageInfoController.OpenedFromSource.MENU,
/*offlinePageLoadUrlDelegate=*/ new ChromePageInfoControllerDelegate(this, webContents,
new OfflinePageUtils.TabOfflinePageLoadUrlDelegate(tab), /*offlinePageLoadUrlDelegate=*/
new ChromePageInfoControllerDelegate(this, webContents)); new OfflinePageUtils.TabOfflinePageLoadUrlDelegate(tab)));
return true; return true;
} }
return super.onMenuOrKeyboardAction(id, fromMenu); return super.onMenuOrKeyboardAction(id, fromMenu);
......
...@@ -202,9 +202,9 @@ public class StatusViewCoordinator implements View.OnClickListener, UrlTextChang ...@@ -202,9 +202,9 @@ public class StatusViewCoordinator implements View.OnClickListener, UrlTextChang
WebContents webContents = tab.getWebContents(); WebContents webContents = tab.getWebContents();
PageInfoController.show(activity, webContents, null, PageInfoController.show(activity, webContents, null,
PageInfoController.OpenedFromSource.TOOLBAR, PageInfoController.OpenedFromSource.TOOLBAR,
/*offlinePageLoadUrlDelegate=*/ new ChromePageInfoControllerDelegate(activity, webContents,
new OfflinePageUtils.TabOfflinePageLoadUrlDelegate(tab), /*offlinePageLoadUrlDelegate=*/
new ChromePageInfoControllerDelegate(activity, webContents)); new OfflinePageUtils.TabOfflinePageLoadUrlDelegate(tab)));
} }
/** /**
......
...@@ -6,14 +6,20 @@ package org.chromium.chrome.browser.page_info; ...@@ -6,14 +6,20 @@ package org.chromium.chrome.browser.page_info;
import android.content.Intent; import android.content.Intent;
import android.text.SpannableString; import android.text.SpannableString;
import android.text.TextUtils;
import androidx.annotation.IntDef; import androidx.annotation.IntDef;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import org.chromium.base.Consumer; import org.chromium.base.Consumer;
import org.chromium.chrome.R; import org.chromium.chrome.R;
import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.ChromeActivity;
import org.chromium.chrome.browser.feature_engagement.TrackerFactory; import org.chromium.chrome.browser.feature_engagement.TrackerFactory;
import org.chromium.chrome.browser.instantapps.InstantAppsHandler; import org.chromium.chrome.browser.instantapps.InstantAppsHandler;
import org.chromium.chrome.browser.offlinepages.OfflinePageItem;
import org.chromium.chrome.browser.offlinepages.OfflinePageUtils;
import org.chromium.chrome.browser.offlinepages.OfflinePageUtils.OfflinePageLoadUrlDelegate;
import org.chromium.chrome.browser.omnibox.ChromeAutocompleteSchemeClassifier; import org.chromium.chrome.browser.omnibox.ChromeAutocompleteSchemeClassifier;
import org.chromium.chrome.browser.previews.PreviewsAndroidBridge; import org.chromium.chrome.browser.previews.PreviewsAndroidBridge;
import org.chromium.chrome.browser.previews.PreviewsUma; import org.chromium.chrome.browser.previews.PreviewsUma;
...@@ -35,12 +41,23 @@ import org.chromium.ui.text.SpanApplier.SpanInfo; ...@@ -35,12 +41,23 @@ import org.chromium.ui.text.SpanApplier.SpanInfo;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.text.DateFormat;
import java.util.Date;
/** /**
* Chrome's implementation of PageInfoControllerDelegate, that provides Chrome-specific info to * Chrome's implementation of PageInfoControllerDelegate, that provides Chrome-specific info to
* PageInfoController. It also contains logic for Chrome-specific features, like {@link Previews} * PageInfoController. It also contains logic for Chrome-specific features, like {@link Previews}
*/ */
public class ChromePageInfoControllerDelegate implements PageInfoControllerDelegate { public class ChromePageInfoControllerDelegate implements PageInfoControllerDelegate {
@IntDef({OfflinePageState.NOT_OFFLINE_PAGE, OfflinePageState.TRUSTED_OFFLINE_PAGE,
OfflinePageState.UNTRUSTED_OFFLINE_PAGE})
@Retention(RetentionPolicy.SOURCE)
public @interface OfflinePageState {
int NOT_OFFLINE_PAGE = 1;
int TRUSTED_OFFLINE_PAGE = 2;
int UNTRUSTED_OFFLINE_PAGE = 3;
}
@IntDef({PreviewPageState.NOT_PREVIEW, PreviewPageState.SECURE_PAGE_PREVIEW, @IntDef({PreviewPageState.NOT_PREVIEW, PreviewPageState.SECURE_PAGE_PREVIEW,
PreviewPageState.INSECURE_PAGE_PREVIEW}) PreviewPageState.INSECURE_PAGE_PREVIEW})
@Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE)
...@@ -53,11 +70,18 @@ public class ChromePageInfoControllerDelegate implements PageInfoControllerDeleg ...@@ -53,11 +70,18 @@ public class ChromePageInfoControllerDelegate implements PageInfoControllerDeleg
private final WebContents mWebContents; private final WebContents mWebContents;
private final ChromeActivity mActivity; private final ChromeActivity mActivity;
private final @PreviewPageState int mPreviewPageState; private final @PreviewPageState int mPreviewPageState;
private String mOfflinePageUrl;
private String mOfflinePageCreationDate;
private @OfflinePageState int mOfflinePageState;
private OfflinePageLoadUrlDelegate mOfflinePageLoadUrlDelegate;
public ChromePageInfoControllerDelegate(ChromeActivity activity, WebContents webContents) { public ChromePageInfoControllerDelegate(ChromeActivity activity, WebContents webContents,
OfflinePageLoadUrlDelegate offlinePageLoadUrlDelegate) {
mWebContents = webContents; mWebContents = webContents;
mActivity = activity; mActivity = activity;
mPreviewPageState = getPreviewPageStateAndRecordUma(); mPreviewPageState = getPreviewPageStateAndRecordUma();
initOfflinePageParams();
mOfflinePageLoadUrlDelegate = offlinePageLoadUrlDelegate;
} }
private Profile profile() { private Profile profile() {
...@@ -84,6 +108,28 @@ public class ChromePageInfoControllerDelegate implements PageInfoControllerDeleg ...@@ -84,6 +108,28 @@ public class ChromePageInfoControllerDelegate implements PageInfoControllerDeleg
return previewPageState; return previewPageState;
} }
private void initOfflinePageParams() {
mOfflinePageState = OfflinePageState.NOT_OFFLINE_PAGE;
OfflinePageItem offlinePage = OfflinePageUtils.getOfflinePage(mWebContents);
if (offlinePage != null) {
mOfflinePageUrl = offlinePage.getUrl();
if (OfflinePageUtils.isShowingTrustedOfflinePage(mWebContents)) {
mOfflinePageState = OfflinePageState.TRUSTED_OFFLINE_PAGE;
} else {
mOfflinePageState = OfflinePageState.UNTRUSTED_OFFLINE_PAGE;
}
// Get formatted creation date of the offline page. If the page was shared (so the
// creation date cannot be acquired), make date an empty string and there will be
// specific processing for showing different string in UI.
long pageCreationTimeMs = offlinePage.getCreationTimeMs();
if (pageCreationTimeMs != 0) {
Date creationDate = new Date(offlinePage.getCreationTimeMs());
DateFormat df = DateFormat.getDateInstance(DateFormat.MEDIUM);
mOfflinePageCreationDate = df.format(creationDate);
}
}
}
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
...@@ -194,4 +240,68 @@ public class ChromePageInfoControllerDelegate implements PageInfoControllerDeleg ...@@ -194,4 +240,68 @@ public class ChromePageInfoControllerDelegate implements PageInfoControllerDeleg
public VrHandler getVrHandler() { public VrHandler getVrHandler() {
return VrModuleProvider.getDelegate(); return VrModuleProvider.getDelegate();
} }
/**
* {@inheritDoc}
*/
@Override
public String getOfflinePageUrl() {
return mOfflinePageUrl;
}
/**
* {@inheritDoc}
*/
@Override
public boolean isShowingOfflinePage() {
return mOfflinePageState != OfflinePageState.NOT_OFFLINE_PAGE && !isShowingPreview();
}
/**
* {@inheritDoc}
*/
@Override
public void initOfflinePageUiParams(
PageInfoViewParams viewParams, Consumer<Runnable> runAfterDismiss) {
if (isShowingOfflinePage() && OfflinePageUtils.isConnected()) {
viewParams.openOnlineButtonClickCallback = () -> {
runAfterDismiss.accept(() -> {
// Attempt to reload to an online version of the viewed offline web page.
// This attempt might fail if the user is offline, in which case an offline
// copy will be reloaded.
OfflinePageUtils.reload(mWebContents, mOfflinePageLoadUrlDelegate);
});
};
} else {
viewParams.openOnlineButtonShown = false;
}
}
/**
* {@inheritDoc}
*/
@Override
@Nullable
public String getOfflinePageConnectionMessage() {
if (mOfflinePageState == OfflinePageState.TRUSTED_OFFLINE_PAGE) {
return String.format(mActivity.getString(R.string.page_info_connection_offline),
mOfflinePageCreationDate);
} else if (mOfflinePageState == OfflinePageState.UNTRUSTED_OFFLINE_PAGE) {
// For untrusted pages, if there's a creation date, show it in the message.
if (TextUtils.isEmpty(mOfflinePageCreationDate)) {
return mActivity.getString(
R.string.page_info_offline_page_not_trusted_without_date);
} else {
return String.format(
mActivity.getString(R.string.page_info_offline_page_not_trusted_with_date),
mOfflinePageCreationDate);
}
}
return null;
}
@VisibleForTesting
void setOfflinePageStateForTesting(@OfflinePageState int offlinePageState) {
mOfflinePageState = offlinePageState;
}
} }
...@@ -134,8 +134,9 @@ import org.chromium.ui.modelutil.PropertyModel; ...@@ -134,8 +134,9 @@ import org.chromium.ui.modelutil.PropertyModel;
if (mChromeActivity == null) return; if (mChromeActivity == null) return;
PageInfoController.show(mChromeActivity, mWebContentsRef, null, PageInfoController.show(mChromeActivity, mWebContentsRef, null,
PageInfoController.OpenedFromSource.TOOLBAR, PageInfoController.OpenedFromSource.TOOLBAR,
/*offlinePageLoadUrlDelegate=*/ new ChromePageInfoControllerDelegate(mChromeActivity, mWebContentsRef,
new OfflinePageUtils.WebContentsOfflinePageLoadUrlDelegate(mWebContentsRef), /*offlinePageLoadUrlDelegate=*/
new ChromePageInfoControllerDelegate(mChromeActivity, mWebContentsRef)); new OfflinePageUtils.WebContentsOfflinePageLoadUrlDelegate(
mWebContentsRef)));
}; };
} }
...@@ -602,9 +602,9 @@ public class CustomTabToolbar extends ToolbarLayout implements View.OnLongClickL ...@@ -602,9 +602,9 @@ public class CustomTabToolbar extends ToolbarLayout implements View.OnLongClickL
if (activity == null) return; if (activity == null) return;
PageInfoController.show(activity, webContents, getContentPublisher(), PageInfoController.show(activity, webContents, getContentPublisher(),
PageInfoController.OpenedFromSource.TOOLBAR, PageInfoController.OpenedFromSource.TOOLBAR,
/*offlinePageLoadUrlDelegate=*/ new ChromePageInfoControllerDelegate(activity, webContents,
new OfflinePageUtils.TabOfflinePageLoadUrlDelegate(currentTab), /*offlinePageLoadUrlDelegate=*/
new ChromePageInfoControllerDelegate(activity, webContents)); new OfflinePageUtils.TabOfflinePageLoadUrlDelegate(currentTab)));
}); });
} }
......
...@@ -66,10 +66,10 @@ public class PageInfoControllerTest { ...@@ -66,10 +66,10 @@ public class PageInfoControllerTest {
Tab tab = mActivityTestRule.getActivity().getActivityTab(); Tab tab = mActivityTestRule.getActivity().getActivityTab();
PageInfoController.show(mActivityTestRule.getActivity(), tab.getWebContents(), null, PageInfoController.show(mActivityTestRule.getActivity(), tab.getWebContents(), null,
PageInfoController.OpenedFromSource.MENU, PageInfoController.OpenedFromSource.MENU,
/*offlinePageLoadUrlDelegate=*/ new ChromePageInfoControllerDelegate(mActivityTestRule.getActivity(),
new OfflinePageUtils.TabOfflinePageLoadUrlDelegate(tab), tab.getWebContents(),
new ChromePageInfoControllerDelegate( /*offlinePageLoadUrlDelegate=*/
mActivityTestRule.getActivity(), tab.getWebContents())); new OfflinePageUtils.TabOfflinePageLoadUrlDelegate(tab)));
}); });
} }
...@@ -86,14 +86,16 @@ public class PageInfoControllerTest { ...@@ -86,14 +86,16 @@ public class PageInfoControllerTest {
testUrl, PageTransition.TYPED, mActivityTestRule.getActivity().getActivityTab()); testUrl, PageTransition.TYPED, mActivityTestRule.getActivity().getActivityTab());
TestThreadUtils.runOnUiThreadBlocking(() -> { TestThreadUtils.runOnUiThreadBlocking(() -> {
Tab tab = mActivityTestRule.getActivity().getActivityTab(); Tab tab = mActivityTestRule.getActivity().getActivityTab();
ChromePageInfoControllerDelegate chromePageInfoControllerDelegate =
new ChromePageInfoControllerDelegate(mActivityTestRule.getActivity(),
tab.getWebContents(),
/*offlinePageLoadUrlDelegate=*/
new OfflinePageUtils.TabOfflinePageLoadUrlDelegate(tab));
chromePageInfoControllerDelegate.setOfflinePageStateForTesting(
ChromePageInfoControllerDelegate.OfflinePageState.NOT_OFFLINE_PAGE);
PageInfoController pageInfo = new PageInfoController(mActivityTestRule.getActivity(), PageInfoController pageInfo = new PageInfoController(mActivityTestRule.getActivity(),
tab.getWebContents(), ConnectionSecurityLevel.NONE, /*offlinePageUrl=*/null, tab.getWebContents(), ConnectionSecurityLevel.NONE, /*publisher=*/null,
/*offlinePageCreationDate=*/null, chromePageInfoControllerDelegate);
PageInfoController.OfflinePageState.NOT_OFFLINE_PAGE, /*publisher=*/null,
/*offlinePageLoadUrlDelegate=*/
new OfflinePageUtils.TabOfflinePageLoadUrlDelegate(tab),
new ChromePageInfoControllerDelegate(
mActivityTestRule.getActivity(), tab.getWebContents()));
PageInfoView pageInfoView = pageInfo.getPageInfoViewForTesting(); PageInfoView pageInfoView = pageInfo.getPageInfoViewForTesting();
// Test that the title contains the Unicode hostname rather than strict equality, as // Test that the title contains the Unicode hostname rather than strict equality, as
// the test server will be bound to a random port. // the test server will be bound to a random port.
......
...@@ -6,6 +6,8 @@ package org.chromium.components.page_info; ...@@ -6,6 +6,8 @@ package org.chromium.components.page_info;
import android.content.Intent; import android.content.Intent;
import androidx.annotation.Nullable;
import org.chromium.base.Consumer; import org.chromium.base.Consumer;
import org.chromium.components.omnibox.AutocompleteSchemeClassifier; import org.chromium.components.omnibox.AutocompleteSchemeClassifier;
import org.chromium.components.page_info.PageInfoView.PageInfoViewParams; import org.chromium.components.page_info.PageInfoView.PageInfoViewParams;
...@@ -66,4 +68,29 @@ public interface PageInfoControllerDelegate { ...@@ -66,4 +68,29 @@ public interface PageInfoControllerDelegate {
* Returns a VrHandler for Page Info UI. * Returns a VrHandler for Page Info UI.
*/ */
public VrHandler getVrHandler(); public VrHandler getVrHandler();
/**
* Gets the Url of the offline page being shown if any. Returns null otherwise.
*/
@Nullable
String getOfflinePageUrl();
/**
* Whether the page being shown is an offline page.
*/
boolean isShowingOfflinePage();
/**
* Initialize viewParams with Offline Page UI info, if any.
* @param viewParams The PageInfoViewParams to set state on.
* @param consumer Used to set "open Online" button callback for offline page.
*/
void initOfflinePageUiParams(PageInfoViewParams viewParams, Consumer<Runnable> runAfterDismiss);
/**
* Return the connection message shown for an offline page, if appropriate.
* Returns null if there's no offline page.
*/
@Nullable
String getOfflinePageConnectionMessage();
} }
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