Update MainActivity handling to not use the Homescreen #815
Conversation
61faf4e
to
4b5ebc3
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This works but I'm concerned about maintainability:
- I don't see how this implementation will support a native Pocket video feed
- The back button handling is janky: hitting back on the last web page pops the BrowserFragment from the stack and the session observer recreates it in order to show the overlay. I guess we'll fix that in [Home] Consolidate back button behavior and ensure back behavior is correct #766 though?
- I assume we're drawing the overlay - and will be with other views like Pocket video - over a blank WebView. This creates overdraw which will affect performance.
I'd like it if we just came up with one solution to support Pocket and the overlay first but we can land this and iterate on it too.
@@ -232,6 +234,12 @@ public boolean shouldOverrideUrlLoading(AmazonWebView view, String url) { | |||
return true; | |||
} | |||
|
|||
// Home screen loads a blank page and shows the overlay | |||
if (url.equals(URL_HOME)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
url can be null: URL_HOME.equals(url)
@@ -232,6 +234,12 @@ public boolean shouldOverrideUrlLoading(AmazonWebView view, String url) { | |||
return true; | |||
} | |||
|
|||
// Home screen loads a blank page and shows the overlay | |||
if (url.equals(URL_HOME)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's fine to do the simple thing for now but considering we expect other pages to exist here (e.g. the Pocket feed), we'll want to do something more generic in the future (maybe a map from url -> Fragment?)
if (url.equals(URL_HOME)) { | ||
// TODO: show browser overlay | ||
view.clearView(); // Deprecated in Android WebView, but AmazonWebView doesn't conform |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we should use deprecated methods: Google has a history of breaking them. Thoughts:
- Load about:blank
- Override the page content to load our own blank page
- If
firefox:
URL, replace WebView with native content (this is necessary for Pocket videos anyway).
@@ -234,9 +234,10 @@ public boolean shouldOverrideUrlLoading(AmazonWebView view, String url) { | |||
return true; | |||
} | |||
|
|||
// Home screen loads a blank page and shows the overlay | |||
// Home screen should show a blank webview. Since WebView doesn't (and shouldn't) have a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: -> "blank page"? Also, why should the home screen be blank? Why can't we just show the home screen for the homescreen? Is it about clearing the webView resources?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Homescreen isn't separate from BrowserFragment, so the webview is always loaded.
@@ -173,6 +173,13 @@ class BrowserFragment : IWebViewLifecycleFragment() { | |||
return layout | |||
} | |||
|
|||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Can we leave this in onCreateView
?
My understanding of the intended use is that the view doing the inflating overrides onCreateView
while its super/sub classes can handle the inflation with onViewCreated
: using them both in a single class is really confusing.
@@ -173,6 +173,13 @@ class BrowserFragment : IWebViewLifecycleFragment() { | |||
return layout | |||
} | |||
|
|||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will only work when BrowserFragment is first created. What about loading Pocket videos?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume that Pocket Videos will just be loading a fragment anyway. This breaks history behavior if users expect "pocket to be a web page" and want to go "back" to it, but since back doesn't work on Youtube anyway (#733), I didn't handle that case here.
@@ -173,8 +173,12 @@ class BrowserFragment : IWebViewLifecycleFragment() { | |||
return layout | |||
} | |||
|
|||
private fun isHomepage(): Boolean { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: val isUrlEqualToHomepage: Boolean get() = session...
BrowserFragment isn't a URL so I don't love adding accessor methods that should act on URLs to BrowserFragment. Ideally, url
would be a class that isn't String so we could add a url.isHomepage
property. I would prefer not to propagate these style of accessor methods but since our team is small (and we can sort of avoid broken window theory through tough reviews), it's probably fine for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, I think this a being a little nitpicky - the current alternative is to have url == HOME_URL
everywhere, which I think is worse. At least this is an easy single accessor, so if we want to change it, it's easy to find.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case, it's nitpicky, yes. But if the trend continues, BrowserFragment becomes a really long file because it acts as a callthrough for functionality defined elsewhere: this is why the Focus BrowserFragment seems more complicated than ours. I'd like to stop this as soon possible.
private lateinit var uiLifecycleCancelJob: Job | ||
|
||
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? { | ||
val rootView = inflater!!.inflate(R.layout.fragment_home, container, false) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to remove this layout?
@@ -193,7 +197,6 @@ class BrowserFragment : IWebViewLifecycleFragment() { | |||
webView?.goBack() | |||
TelemetryWrapper.browserBackControllerEvent() | |||
} | |||
browserOverlay.isVisible -> setOverlayVisibleByUser(false) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pressing back from the home screen doesn't close the app.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmmm yeah this is a little more complicated - short of hardcoding "if ishomepage && !hashistory", I'm not sure how else we should do this. Can handle this in #766 .
@@ -234,9 +234,10 @@ public boolean shouldOverrideUrlLoading(AmazonWebView view, String url) { | |||
return true; | |||
} | |||
|
|||
// Home screen loads a blank page and shows the overlay | |||
// Home screen should show a blank webview. Since WebView doesn't (and shouldn't) have a | |||
// handle to browser UI, this url can't be used to load the overlay. | |||
if (url.equals(URL_HOME)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want the URL bar to display "firefox:home"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is what I was looking for: nice! The two main issues:
shouldOverrideLoading
is called twice- I think we should call
ScreenController.showBrowserScreenForUrl
instead of creating a session directly.
} | ||
ScreenController.showBrowserScreenForCurrentSession(supportFragmentManager, sessionManager) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: This is going to get called twice: once now and once when the session is created. I think you should do this instead:
if (sessions.isEmpty()) {
ScreenController.showBrowserScreenForUrl(URL_HOME)
} else {
ScreenController.showBrowserScreenForCurrentSession(...)
}
const val URL_HOME = "firefox:home" | ||
const val APP_URL_PREFIX = "firefox:" | ||
const val HOME_SUFFIX = "home" | ||
const val APP_URL_HOME = APP_URL_PREFIX + HOME_SUFFIX |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: "${APP_URL_PREFIX}home" and rm constant above (since it's only used once).
@@ -288,6 +287,13 @@ private class BrowserIWebViewCallback( | |||
override fun onBlockingStateChanged(isBlockingEnabled: Boolean) {} | |||
|
|||
override fun onLongPress(hitTarget: IWebView.HitTarget) {} | |||
override fun shouldInterceptRequest(url: String) { | |||
launch(UI) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: make a comment that this may not be called from the UI thread and that's why we launch
@@ -112,6 +112,7 @@ internal class FirefoxAmazonWebView( | |||
// called by webview when clicking on a link, and not when opening a new page for the | |||
// first time using loadUrl(). | |||
if (!client.shouldOverrideUrlLoading(this, url)) { | |||
callback?.shouldInterceptRequest(url) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This gets called twice: here and in shouldInterceptRequest. I don't think this call is necessary but if you don't, the screen flashes when loadUrl
is initially called: I think this is because shouldInterceptRequest
gets called from a background thread so the webView has time to blank (white) before it displays the overlay while calling shouldInterceptRequest
from loadUrl
is on the UI thread and happens ASAP. One hacky way to fix this is to set the default color of the WebView.
I think we should try to remove the redundant call but I'm not sure the best way to fix the flash-in issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, okay - I'll file a follow-up for this (#841), but take it out for now. We could possibly do this in onViewCreated for BrowserFragment, now that we handle that for other cases too.
return super.shouldInterceptRequest(view, request); | ||
} | ||
|
||
private ByteArrayInputStream makeEmptyDataStream() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: -> getBlankPageStream
or getBlankPageInputStream()
switch (request) { | ||
case APP_URL_HOME: | ||
// Home screen should show a blank webview behind the overlay, but keep the url. | ||
callback.shouldInterceptRequest(request); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: -> onShouldInterceptRequest
. If you don't expect it to replace the method, you should make it clear this is a callback.
@@ -111,9 +114,24 @@ public void onLoadResource(AmazonWebView view, String url) { | |||
// WebResourceRequest was added in API21 and there is no equivalent AmazonWebResourceRequest | |||
@Override | |||
public AmazonWebResourceResponse shouldInterceptRequest(AmazonWebView view, String request) { | |||
if ((request != null && request.startsWith(APP_URL_PREFIX))) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: This if has an extra set of parenthesis.
// Home screen should show a blank webview behind the overlay, but keep the url. | ||
callback.shouldInterceptRequest(request); | ||
final ByteArrayInputStream homeDataStream = makeEmptyDataStream(); | ||
return new AmazonWebResourceResponse("text/html", "utf-8", homeDataStream); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: add a comment explaining why we blank the page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assumed that this was sufficient:
// Home screen should show a blank webview behind the overlay, but keep the url.
TC errors, but we need to do a string export to get rid of localized strings that were removed. |
This only changes the calling order from MainActivity, and removes HomeFragment - #768 does the UI changes.