Closed Bug 1337341 Opened 7 years ago Closed 7 years ago

Handle the user navigating out the scope of the webapp

Categories

(Firefox for Android Graveyard :: General, defect)

defect
Not set
normal

Tracking

(firefox55 verified)

VERIFIED FIXED
Firefox 55
Tracking Status
firefox55 --- verified

People

(Reporter: daleharvey, Assigned: daleharvey)

References

Details

Attachments

(3 files, 3 obsolete files)

      No description provided.
Blocks: 1285858
Assignee: nobody → dale
Summary: Show and Hide chrome when navigating to manifest → Show and Hide chrome when navigating url within installed manifest scope
Summary: Show and Hide chrome when navigating url within installed manifest scope → Hide chrome when navigating url within installed manifest scope
STR: run Fennec with pref("manifest.install.enabled", true);

Visit twitter.com and Page -> Add to Homescreen, on future visits to twitter.com the url chrome should be hidden and should reappear when the user navigates outside of the scope of twitter.com
Sebastian, was wondering if you could point me to the general direction of how to do this, at some point in browser.js on page load I will be checking if we are currently inside an app scope and send an appscopeentered/appscopeleft messages to Tabs.java at which point we hide / show the browser chrome

I dont want a new instance of the browser / geckoview without a URL bar, I just want the url bar + related chrome to disappear and not be shown again on scroll. For an existing example, visit pokedex.org as a pwa on chrome, scroll down to the bottom and click one of the links then press back, Chrome uses a mini url bar thing but I think it should be the full browser chrome and allow users to use find etc

Cheers
Flags: needinfo?(s.kaspari)
Actually this is fairly simple and I have a bunch of other questions so I will take off the needinfo, the flags are not going to be useful as those are android constructs, not relating to firefox chrome but setVisible seems to work good
Flags: needinfo?(s.kaspari)
(In reply to Dale Harvey (:daleharvey) from comment #2)
> I dont want a new instance of the browser / geckoview without a URL bar, I
> just want the url bar + related chrome to disappear and not be shown again
> on scroll. For an existing example, visit pokedex.org as a pwa on chrome,
> scroll down to the bottom and click one of the links then press back, Chrome
> uses a mini url bar thing but I think it should be the full browser chrome
> and allow users to use find etc

I don't think I agree. If you look at the recent apps screen then they are actually like separate apps and you can switch between browser and "web app". Just hiding the browser chrome will mean you end up with just the app (There's only always one BrowserApp and there can't be multiple by design). Of course you could add multiple entries ("documents") to the recent apps list, pointing to the browser activity and when selected dynamically switch tabs and hide/show the browser chrome - but this gets messy and complicated pretty fast. Instead separate activities (like we do for custom tabs!) are pretty easy to implement and instead of revealing the toolbar we could switch to the browser and hand-off the tab to it.
If we are going to implement fully separate apps/APKs like chrome does then a separate activity will be helpful too.
(I am gonna call web pages with their own entry in the task switcher appwindows, if anyone has a better term happy to change just want to make it clear)

Sorry I wasnt clearer in the spec, so hiding / showing some type of chrome needs to happen even when we have implemented appwindows, chrome has a "mini url bar" type thing that is shown when you navigate out of origin however it only shows the url, it is not editable nor lets you use the rest of the browser functionality (share url, print, find in page etc)

Similarly one of the primary criticisms of the chromes implementation pwa is that the url bar is entirely non accessible when in appwindows, that is something the chrome team are looking to fix and something I would prefer to avoid on an initial implementation.

Opera have the activity hand-off implementation for showing the url bar and it is not friendly, you arent showing the url of the current page you are opening an entirely new page, the current state including form data is wiped etc

What I would like to do is:

1 BrowserApp, opened with the firefox icon, there is only ever 1, has tabs and works exactly as it does now.

N BrowserAppWindows, opens with manifest icons, as many in taskswitcher as opened, has functionality of chrome (find in page) but no tabs, opens without chrome visible but chrome may be shown by user gesture or by navigating out of origin
After talking to Sebastian going to work on https://bugzilla.mozilla.org/show_bug.cgi?id=1336355 before this one, will leave a working patch in progress
Attached patch WIP of hiding chrome (obsolete) — Splinter Review
Assignee: dale → nobody
Summary: Hide chrome when navigating url within installed manifest scope → Handle the user navigating out the scope of the webapp
Assignee: nobody → dale
We need to handle when the user leaves the scope of an installed app, the page we navigate to may not be built to support a mobile ui and leave the user stuck. Related is that we may want to provide the URL bar even when in standalone mode as it gives the user the browser features (refresh, forward, find in page etc)

There are 2 options:

1. In Chrome they show a small url bar when navigating out of scope but browser features are never offered within the pwa, its possible to offer a 'jump to browser' gesture as opera experiments, however the switch between applications (from the web app to the browser) makes for a confusing arrangement in terms of tabs + history

2. In Firefox OS, the chrome was hidden by default when in app scope and shown when not, this is a video of a very basic prototype https://drive.google.com/file/d/0B40bv5uHi-SHYnRJN2ZKbFhTNnc/view?usp=sharing of this functionality (the tabs button would be hidden in this mode)

#1 is very simple, we just add a toolbar on top of https://bugzilla.mozilla.org/show_bug.cgi?id=1336355 however is a very sub par experience, it gives a small feature of native apps and loses all benefits of the web #2 is more complicated but a far nicer experience.

Sebastian/Snorp do you think #2 is feasible at this point and if so any tips for how to go forward? Should I just change BrowserApp to not be a singleTask and see what breaks?
Flags: needinfo?(snorp)
Flags: needinfo?(s.kaspari)
Can you explain what the confusing part in #1 is? As an Android user I would assume that clicking a link in an app opens my browser. As a user I'd expect Twitter the web app behave like Twitter the native app.

> Sebastian/Snorp do you think #2 is feasible at this point and if so any tips for how to go forward? Should I just change BrowserApp to not be a singleTask and see what breaks?

I expect a bunch of things to break. There's code that expects that there will be only one BrowserApp. But this is also by design: We only ever want one Browser. We do not want multiple instances (with the same set of tabs) of it.

I think 2 is only a good behavior as long as you are only looking at the currently visible app. If you reveal the chrome you will have another full featured browser in the list of recent apps. This is actually confusing. I can't fully grasp what the advantage over switching to the browser is. As mentioned before we can make the switch much more visible appealing then it is by default (transition animations).
Flags: needinfo?(s.kaspari)
> Can you explain what the confusing part in #1 is? As an Android user I 
> would assume that clicking a link in an app opens my browser. As a user 
> I'd expect Twitter the web app behave like Twitter the native app.

Clicking a link with target=_blank as twitter does will open links in the browser (the twitter web app and native app are a very similiar experience) this is for when a user clicks a non _blank link outside the scope of the app,

If we intercepted this click and opened it in the browser then we break the authentication flow for most sites that use oauth, the 'app' would left on the login page, the browser would complete the auth flow then if the user wanted to be using the app they would need go back to the app, close it (because they cant refresh inside app mode) and reopen it to resume using the app version

Auth flows is just one obvious example, there are plenty of times when authors want users to be able to navigate in and out of app scope in the same window without having to jump between apps, its a fundamental expectation of the web that links replace their current content and target=_blank open in new windows and breaking that assumption causes a lot of problems (also makes for a super confusing back button)

> I think 2 is only a good behavior as long as you are only looking at the currently visible app. 
> If you reveal the chrome you will have another full featured browser in the list of recent apps.

There will only ever be one instance of 'Firefox' in the recent apps list and it will maintain the only list of tabs. If you have opened multiple web apps even if they have chrome shown they will have title and icons in the app switcher that relate to their content and will not have access to tabs

URL Access is an upcoming feature in Android Chrome (https://twitter.com/slightlylate/status/755564702495715330) not being able to access it within apps has been one of the largest critisisms (https://adactio.com/journal/10708), we have already done user testing, implementation and seen this app + web navigation model be extremely successful (one of the only successful things in fxos). It is a start on bringing some of the advantages of native apps while maintaining all the advantages of the web instead of being a sub par implementation of both.
I would still like the chance to go with my proposal here, jumping from the app to the browser when we want to access the url bar is not providing new features to the app, users can already open urls in the browser but they want to be within the app context.

However it is a relatively large change and without more resources (especially considering I may be taken off pwa work later on) I think it is a safer bet that I fix this by simply copying chrome behavior of showing a mini url bar when navigating out of scope. That should be a comparatively simple patch that I can finish and focus on getting the pref enabled by default in release before (hopefully) someone is able to put resources into a more user friendly version.
Flags: needinfo?(snorp)
(In reply to Sebastian Kaspari (:sebastian) from comment #5)
> Instead separate activities (like we do for custom tabs!) are
> pretty easy to implement and instead of revealing the toolbar we could
> switch to the browser and hand-off the tab to it.
> If we are going to implement fully separate apps/APKs like chrome does then
> a separate activity will be helpful too.

I need to see how bug 1346004 works out, but if it does work as expected and we're going for it, having a separate activity based on GeckoApp (just as the CustomTabsActivity) would indeed be the direction to go for separating web apps from the normal tabs list.

(In reply to Dale Harvey (:daleharvey) from comment #11)
> Clicking a link with target=_blank as twitter does will open links in the
> browser (the twitter web app and native app are a very similiar experience)
> this is for when a user clicks a non _blank link outside the scope of the
> app,
> 
> If we intercepted this click and opened it in the browser then we break the
> authentication flow for most sites that use oauth, the 'app' would left on
> the login page, the browser would complete the auth flow then if the user
> wanted to be using the app they would need go back to the app, close it
> (because they cant refresh inside app mode) and reopen it to resume using
> the app version

Note that at least at the moment, behind the scenes everything is still covered by the same Gecko instance, so switching to browser mode and back would just be a question of moving things around in the Java UI between the different Tabs instances and switching back and forth between BrowserApp and the hypothetical WebAppActivity, but it wouldn't affect the actual web navigation flow.
Cc'ing Andreas and Joe

So I tried to make an example of what would break, but guessing I need to install HTTPS for Opera to install this and too much work to make a simple point :)

http://junk.arandomurl.com/testapp.html basically if you do a redirect to something outwith the scope of your webapp as part of your auth then every time the user authenticates they will be booted from the application into the browser. This is something we found to be fairly common in Firefox OS and its a fairly common oauth flow.
Attachment #8839064 - Attachment is obsolete: true
So here is a patch that behaves similiar but not identical to chrome, if a user navigates out of the scope of an application then the current url is shown.

This is simpler implementation wise than jumping out of the browser and avoids some pretty big UX issues, Joe do you think we could get a UX review on this? Thanks
Flags: needinfo?(jcheng)
flagging Jack for standalone mode UI
Flags: needinfo?(jalin)
So the open question here is to decide either a. launch a full browser or b. render page within the same standalone mode, with a mini URL bar.

Besides the UX, in the meeting earlier today we talked about potential security concerns for option b.
Selena, could you share some thoughts or point us to the person who might?
Flags: needinfo?(sdeckelmann)
Flags: needinfo?(sdeckelmann) → needinfo?(dveditz)
To explain the issue for UX + Security, A user visits some website that has a manifest, like pokedex.org, they decide (or are prompted after multiple visits) if they want to add this to the homescreen and they do so.

When the site is launched from the homescreen it is in standalone mode as per the manifest, this means there is no url bar shown while the user navigates the website. However if the user clicks out of the scope of the manifest then they are no longer considered within the 'app' and we need to decide how to behave. (If you want to try this, add pokedex.org to your homescreen, open it and scroll to the bottom and click on one of the footer links)

Opera intercept the click of the link, leave app in its current state and open the full browser with the clicked url. This behaviour is similiar to how native apps with web links work.

Chrome navigates the clicked link but shows a 'mini url bar' as shown in (https://bugzilla.mozilla.org/attachment.cgi?id=8850554). This warns the user that they are no longer within the same scope as the bookmark they launched from the homescreen, they show the domain and the padlock

Firefox OS used to navigate the link but show the full browser chrome

Andreas mentioned that Opera implemented that because they were worried about content being able to spoof the url bar, as you can see from the screenshots it would be trivial for content to have a link that when pressed had content show a mini url bar with "paypal.com" and a paypal login form. However in that scenario it would need to be the specific web content that users have previously visited and bookmarked to be spoofing them, it wouldnt be possible for arbitrary web content. The act of saving that domain to the homescreen is an indication that the user trusts that content to not purposefully trick the user

In future versions I do want to make it possible to access the full url bar at any time so the user has the option to trust but verify, given this would be following the expectations of the already widely used chrome implementation that has not seen any significant security issues it would be great if we could get the above patch looked at and merged.
(In reply to Dale Harvey (:daleharvey) from comment #21)
> Chrome navigates the clicked link but shows a 'mini url bar' as shown in
> (https://bugzilla.mozilla.org/attachment.cgi?id=8850554). This warns the
> user that they are no longer within the same scope as the bookmark they
> launched from the homescreen, they show the domain and the padlock

This doesn't seem to be entirely true. When I click a link and "navigate" as in your pokedex.org example it seems to be true, but if the clicked link would open a new window/tab as Twitter does then I get that new window with full browser UI.

Somewhat related: in Desktop Firefox when we "pin" a tab you can navigate within that origin, but if you click a link to navigate to a different origin we instead pop out a new tab. If you followed that model then apps would be limited to a single origin and if the app tries to incorporate unframed content from another origin it breaks the continuity. A "real" app wouldn't do that. If it's a required transition page you'd never get back into the "app" view (though you wouldn't have lost the last "app" page you were on -- it'd still be there in the task switcher).

Chrome's current UI seems to be the minimum safe thing to do, though several downsides as you noted. My biggest security concern is that since it's different from the normal URL bar users might not understand or trust it, or be fooled later by a similar presentation in a web site where the real url bar is scrolled out of sight. (I guess such a page could spoof the full URL bar just as easily and trust the user won't try to scroll down.)

Showing the full URL bar and then hiding it again when you re-enter the PWA scope seems fine.
 
> However in that scenario it would need to be the specific web content that
> users have previously visited and bookmarked to be spoofing them, it wouldnt
> be possible for arbitrary web content. The act of saving that domain to the
> homescreen is an indication that the user trusts that content to not
> purposefully trick the user

Yes, the user might trust nice.org, and that might incorporate a flow through a page _it_ trusts on service.com, but then there might be links where the user can escape out into arbitrary web browsing far from where nice.org thought they'd go. At _some_ point you've got to break out of the "app" UI and show the full browser controls.
Flags: needinfo?(dveditz)
Depends on: 1348686
Depends on: 1351739
(In reply to Daniel Veditz [:dveditz] from comment #22)
> Showing the full URL bar and then hiding it again when you re-enter the PWA
> scope seems fine.
>  
> > However in that scenario it would need to be the specific web content that
> > users have previously visited and bookmarked to be spoofing them, it wouldnt
> > be possible for arbitrary web content. The act of saving that domain to the
> > homescreen is an indication that the user trusts that content to not
> > purposefully trick the user
> 
> Yes, the user might trust nice.org, and that might incorporate a flow
> through a page _it_ trusts on service.com, but then there might be links
> where the user can escape out into arbitrary web browsing far from where
> nice.org thought they'd go. At _some_ point you've got to break out of the
> "app" UI and show the full browser controls.

Strange question perhaps, but would it be possible to launch a custom tab, which is a minimized browser UI of sorts, in such a scenario?
(In reply to Daniel Veditz [:dveditz] from comment #22)
> Showing the full URL bar and then hiding it again when you re-enter the PWA
> scope seems fine.

I'd also be fine with popping a new tab in the browser as we do with pinned tabs. At a quick skim I couldn't see that this behavior is defined in the documentation I could find about PWA's.
Sorry for late reply. After Taipei team members discussion, the suggestions are as below.

When users open the link in PWA added via Fennec, we think we can use Firefox custom tab to open it. Even if the default browser is not Firefox, we still use Firefox custom tab to open the link. It's like Fennec PWA binds Firefox custom tab.

Custom tabs reference:
https://developer.chrome.com/multidevice/android/customtabs


Some thoughts for open questions,

a. launch a full browser
- Switching between apps doesn't provide good seamless experience. 
  
b. render page within the same standalone mode, with a mini URL bar
- Firefox custom tab can have the same transition experience as mini URL bar has, and should be no security issues I guess. And also can have more ability and possibility for PWA developers, such as editable UI like changing background color or adding share button onto custom tab (maybe in the future).

How do you think? :)
ni? to daleharvey for recent comments in here.
Flags: needinfo?(dale)
Yeh we had a meeting about this today, my patch moves things along half way to using the custom toolbar, so I am in the middle of rebasing it and getting it to a landable state, switching to full customtab will be a follow up improvement, patch will be ready for tomorrow
Flags: needinfo?(dale)
So as mentioned above, the plan is to get showing the url working then improve that to a full custom tab view as a later improvement.
Attachment #8849144 - Attachment is obsolete: true
Flags: needinfo?(jcheng)
Flags: needinfo?(jalin)
Attachment #8853303 - Flags: review?(s.kaspari)
Comment on attachment 8853303 [details] [diff] [review]
Show url when navigating out the scope of pwa

I'll redirect to :walkingice. He's been working on the custom tab toolbar, so he should know this code and if there are any pitfalls. :)
Attachment #8853303 - Flags: review?(s.kaspari) → review?(walkingice0204)
Comment on attachment 8853303 [details] [diff] [review]
Show url when navigating out the scope of pwa

Review of attachment 8853303 [details] [diff] [review]:
-----------------------------------------------------------------

Most of the code looks good to me, except some concerns.

::: mobile/android/base/java/org/mozilla/gecko/webapps/WebAppActivity.java
@@ +56,5 @@
>          loadManifest(getIntent());
> +
> +        final Toolbar toolbar = (Toolbar) findViewById(R.id.actionbar);
> +        setSupportActionBar(toolbar);
> +        getSupportActionBar().hide();

Could we move this line below `final ActionBar actionBar = getSupportActionBar()`? Then we can reduce one get function call

@@ +79,5 @@
>      }
>  
>      @Override
>      public int getLayout() {
> +        return R.layout.customtabs_activity;

Since this layout xml file will be used in 2 different place(CustomTab and WebApp), I think if we could rename this file, then next developer who edit that file will aware of that file is not only for Custom-Tabs. (But naming is hard to me so I have no idea :-/)

@@ +112,5 @@
> +    public void onDestroy() {
> +      EventDispatcher.getInstance().unregisterUiThreadListener(this,
> +          "Website:AppEntered",
> +          "Website:AppLeft",
> +          null);

Maybe we should unregister Tab listener?

::: mobile/android/base/resources/layout/webapps_action_bar_custom_view.xml
@@ +13,5 @@
> +        android:id="@+id/webapps_action_bar_url"
> +        android:layout_width="match_parent"
> +        android:layout_height="wrap_content"
> +        android:maxLines="1"
> +        android:textColor="@color/android:white"

typo?
Attachment #8853303 - Flags: feedback+
Thanks, I made all the changes except

> Since this layout xml file will be used in 2 different 
> place(CustomTab and WebApp), I think if we could rename this file

Yeh I wasnt sure but I couldnt come up with a name that made any more sense, as it is using custom tabs inside web apps (and will eventually move to a full custom tab implementation) I think leaving it as it is best?

Cheers
Dale
Attachment #8853303 - Attachment is obsolete: true
Attachment #8853303 - Flags: review?(walkingice0204)
Attachment #8853543 - Flags: review?(walkingice0204)
Understood, thanks for that patch :-D
Attachment #8853543 - Flags: review?(walkingice0204) → review+
Pushed by dharvey@mozilla.com:
https://hg.mozilla.org/integration/mozilla-inbound/rev/499067547091
Show url when navigating out the scope of pwa. r=walkingice
https://hg.mozilla.org/mozilla-central/rev/499067547091
Status: NEW → RESOLVED
Closed: 7 years ago
Resolution: --- → FIXED
Target Milestone: --- → Firefox 55
Verified as fixed on Nightly 55 (2017-04-05).
Devices:
- Motorola Nexus 6 (Android 7.0)
- LG G4 (Android 5.1)
- LG G4 (Android 6.0)
Status: RESOLVED → VERIFIED
Depends on: 1353857
Depends on: 1360658
Product: Firefox for Android → Firefox for Android Graveyard
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: