Page MenuHomePhabricator

[Spike 4hrs] Is there a way to detect the which browsers the download button is being delivered to?
Closed, ResolvedPublic

Description

Background

In T182059: Tapping on Download icon has no response in older versions of the Chrome browser including Samsung "Internet" browser. we noticed that the user agent for Samsung's "internet" browser is being recognized as Chrome. Thus, the button is shipped to this browser when it should not be. We would like to know whether we can detect this browser separately from Chrome and remove the download button from this browser

Acceptance criteria

Answer the following:

  • What is the list of browser that are displaying the download button that are not Chrome?

See T182197#3841513, T182197#3849507, and the description of T182059: Tapping on Download icon has no response in older versions of the Chrome browser including Samsung "Internet" browser..

  • On these browsers, does the download as PDF button has the same behavior as Chrome?

Yes. See T182197#3841513.

  • How can we detect these browsers and remove the button from them?

Using UA sniffing. See the description of T182059: Tapping on Download icon has no response in older versions of the Chrome browser including Samsung "Internet" browser..

  • Is the inability for the button to work impacted by Android version, i.e. is there an example of a browser running Android 4.4 and above on which the button does not work?

As @Kaartic says, the likely answer is yes but with the caveat that it'll likely be due a custom ROM being used and is therefore unlikely. Unfortunately, given that the window.print the specification doesn't cover reporting errors (e.g. "this OS doesn't support printing"), it's unlikely that we'll ever know the full extent of this.

Notes

So far, we know (on a device supporting printing):
Similar behaviour :

  • the button behaves the same way as it does in Chrome in version 6.2.x.x of the Samsung "Internet" browser

Dissimilar behaviour:

  • tapping the button does nothing in version 3.5.38.174 of the Samsung "Internet" browser
  • Android supports printing natively from version 4.4, everything on older Android versions might have problems with printing.

Older versions of Chrome can be located here: https://chrome.en.uptodown.com/android/old
Specifically we'd be interested in how the download button works in Chrome 30.x, 40.x, 50.x

Event Timeline

Does the download as PDF button on this browser have the same behavior as Chrome?

Let me state the information, I observed in my device. As stated in T182059,

  • Similar behaviour : the button behaves the same way as it does in Chrome in version 6.2.x.x of the Samsung "Internet" browser
  • Dissimialr behaviour: Tapping the button does nothing in version 3.5.38.174 of the Samsung "Internet" browser.

@Niedzielski - that's a good point. @MBinder_WMF - any thoughts on how to categorize this task? It's not quite proton but related to "proton" work

Does the download as PDF button on this browser have the same behavior as Chrome?

Let me state the information, I observed in my device. As stated in T182059,

  • Similar behaviour : the button behaves the same way as it does in Chrome in version 6.2.x.x of the Samsung "Internet" browser
  • Dissimialr behaviour: Tapping the button does nothing in version 3.5.38.174 of the Samsung "Internet" browser.

Thanks @Kaartic - added to task description.

The answer to the spike is yes per
https://phabricator.wikimedia.org/T182059#3813930

Should we close this? Or perhaps, rephrase as "how" do we detect

ovasileva renamed this task from [Spike] Is there a way to detect the samsung "internet" browser to [Spike 4hrs] Is there a way to detect the samsung "internet" browser.Dec 6 2017, 5:13 PM

Looks like at least those makes use their own build browser based on Chromium: Yandex, Xiaomi, Cyanogen, Puffin, Samsung, Amazon Silk, and Nokia X.

ovasileva renamed this task from [Spike 4hrs] Is there a way to detect the samsung "internet" browser to [Spike 4hrs] Is there a way to detect the which browsers the download button is being delivered to.Dec 6 2017, 5:15 PM
ovasileva updated the task description. (Show Details)
MBinder_WMF renamed this task from [Spike 4hrs] Is there a way to detect the which browsers the download button is being delivered to to [Spike 4hrs] Is there a way to detect the which browsers the download button is being delivered to?.Dec 6 2017, 5:15 PM
ovasileva raised the priority of this task from Medium to High.Dec 7 2017, 3:24 PM

I was a little confused about this so I had a chat with @phuedx to try and tease out my confusion.
It's clear to me that we can detect older versions of Chrome (and thus Samsung browsr) that we've identified where the download button is broken (i.e. it's technically). What's not clear to me is if there are other browsers that are broken that we don't know about.

May I suggest this as a new description?:

In T182059: Tapping on Download icon has no response in older versions of the Chrome browser including Samsung "Internet" browser. we noticed that the user agent for Samsung's "internet" browser is being recognized as Chrome. Thus, the button is shipped to this browser when it should not be.

We would like to identify other browsers which have this problem.

= Acceptance criteria
Answer the following:
[] Are there other browsers that are displaying the download button but are not Chrome?
[] Is the inability for the button to work impacted by Android version?

(Notes etc remain unchanged...)

Just to clarify: Is the assumption here that the changes Samsung makes to the Chromium codebase remove or break the print functionality? (According to this article, which BTW is worth reading in full, "most [of these modifications] have to do with Samsung-specific hardware", e.g. biometrics sensors and Gear VR. One wouldn't expect print features to be in that category.)

What is the list of browser that are displaying the download button that are not Chrome?

I guess the following wikipedia article (!) answers that question to some extent,
https://en.wikipedia.org/wiki/Chromium_(web_browser)#Active

To list the Android browsers I recognize in the list,

  • Brave
  • Samsung Internet

I think we're looking for two things:

Yup I agree with your list! This is my understanding too.

have extremely low usage on android 1, 2, and 3.

We currently do not show the button on these Android versions these browsers do not run JavaScript. Any prints we are seeing there would be using the native browser print function.

@Kaartic that does seem to answer the question to me! Thanks for sharing.

@Kaartic that does seem to answer the question to me! Thanks for sharing.

You're welcome but it seems that list isn't exhaustive. Here's one browser which seems to based on chromium but isn't listed there,

The "Download" button is of course shown and works as expected (shows "Save as PDF" dialog) in the version I tried. FWIW, the User Agent I got for that browser is,

Mozilla/5.0 (Linux; Android 5.1.1; SM-J200G Build/LMY47X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.85 Mobile Safari/537.36

I tried to see what the behaviour was on friend's device which had a custom rom (modified firmware) installed. Surprisingly, the download icon did not work even on Chrome version 63.x !! I could guess that the custom firmware doesn't have the print capability like the original one (I couldn't see 'Print' even in the 'Share' menu). I'm not sure how this issue should be handled, but I'm pretty sure that it should be handled in some way. That's because, the user would not expect the "Download" feature to be dependant upon the "Print" functionality of his device.

Device details
Browser: Google Chrome
Version: 63.x
Android version: 5.1.1
Device model: SM-G531F
Device vendor: Samsung
User agent: Mozilla/5.0 (Linux; Android 5.1.1; SM-G531F Build/LMY48B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.107 Mobile Safari/537.36

I've looked into the issue. I've had a hard time configuring an android virtual device with an old SDK to test various browsers (the ones absent from browserstack). I've found out that printing was enabled in Chrome version 31.0.1650.59.

Printing from Chrome on Android KitKat devices

Since the Samsung Internet browser is based on Chromium and only makes modifications to support various Samsung devices, it's safe to assume that any samsung browser that's based on a newer Chromium will be able to print pages.

According to Samsung, most of the code differences to the standard Chromium code base were introduced in order to support Samsung-specific hardware, such as Gear VR and biometric sensors.

However, I manually tested the various Chrome versions on Android and printing didn't work for version 40.0.2214.109. I couldn't test an earlier version (e.g. 39.0.2171.93) on Android 7.1.2 as Chrome kept crashing. Printing worksed on versions 41, 42, 43, 46 (and presumably works on any new version).

Given a user agent for Chrome on Android (or any derived browser), we can look at <Chrome Rev> and if it's bigger than 40, then show the download button.

Mozilla/5.0 (Linux; <Android Version>; <Build Tag etc.>) AppleWebKit/<WebKit Rev> (KHTML, like Gecko) Chrome/<Chrome Rev> Mobile Safari/<WebKit Rev>

To answer the questions from the task description:

What is the list of browser that are displaying the download button that are not Chrome?

Any browser that's based on Chromium, including Samsung Internet. Although we don't have an exhaustive list, we can sniff the UA and figure out browsers based on Chromium.

On these browsers, does the download as PDF button has the same behavior as Chrome?

Yes, for example, Samsung Internet on Galaxy S3 (Android 4.1) behaves the same as an older Chromium browser (<40) where the download button doesn't trigger a print dialog. Because of the lack of devices/browserstack support I wasn't able to test more devices.

How can we detect these browsers and remove the button from them?

Look at the user agent, and if it shows Chrome version lower than 41, then don't show the print button.

Is the inability for the button to work impacted by Android version, i.e. is there an example of a browser running Android 4.4 and above on which the button does not work?

No it's not impacted. And yes, on Android 7.1.2, printing didn't work on Chrome version 40.0.2214.109.

Please review the outcome of the spike above.

How can we detect these browsers and remove the button from them?

Look at the user agent, and if it shows Chrome version lower than 41, then don't show the print button.

I don't think it's as simple as that, see below.

Is the inability for the button to work impacted by Android version, i.e. is there an example of a browser running Android 4.4 and above on which the button does not work?

No it's not impacted. And yes, on Android 7.1.2, printing didn't work on Chrome version 40.0.2214.109.

Though this answer might apply to the stock android versions installed by the device vendors. This doesn't seem to apply for the custom android versions that people might use. It's not guaranteed that the custom version would have the "Print" functionality even though it's a custom version of Android 5 (an example is stated in my above comment).

So, just seeing the UA and shipping the download icon if the chrome version is above 40 does not solve this issue. There would still be users who would see the download icon but tapping on it would have no reason because their device doesn't have the "Print" functionality and there's no way for them to know the reason why the it didn't work as they don't know the "Download" feature depends on the "Print" functionality of their device. The possible ways around this are,

  1. Show the "Download" icon only if the device supports printing (seems it's not possible per T179529 ??)
  2. Show a better icon to that clearly indicates to the user that the device's print functionality is required. Something like,

Of course this has the issue that the icon would differ from the one used in the survey, but that's the best solution I could come up with.

@Kaartic thanks for the info. According to this Wikipedia page, priting support was added to Android version 5.0:

Support for print previews

Since we cannot reliably feature detect the print functionality in the browser, I'm tempted to say that we cannot detect if the OS as a whole supports priting, let alone custom ROMs.

As for your suggested solutions, we're sniffing the UA because #1 won't work. Showing a better icon won't also solve the problem as it just won't work on the browser you mentioned for example.

I can suggest my workaround (that I read somewhere online): We'll measure the system time right after the user taps on the print button. And we'll measure the time again after we call window.print(). We'll then find the difference in measured times. If it's in the milliseconds, we'll assume printing didn't work. If it's more than a second, then we'll assume the printing dialog worked. The reasoning is that window.print() is blocking, and while the print preview is being generated the code after that blocks. When the function doesn't work at all, then the second time we measure will be close to the first one. Once we figure out whether printing worked or not, we can show a toast with a message if printing didn't work, and hide the download button. We can even set a local storage flag to hide the button in subsequent page loads.

@bmansurov your workaround will not work, as an example on Samsung S2 calling window.print() tries to create a print preview. The print function doesn't exit immediately. for long articles it takes 10-20 seconds to process, then it fires media query event which doesn't match print, and then focus gets back to the browser window.

@Kaartic thanks for the info. According to this Wikipedia page, priting support was added to Android version 5.0:

Support for print previews

Sounds reasonable. Just recently noticed the download icon being shipped to a Chrome browser (version 62.0.3202.84) running on top of Android 4.3. User Agent: Mozilla/5.0 (Linux; Android 4.3; GT-I9300 Build/JSS15J) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36. Of course it did not work! In case you need more information about that, let me know.

Showing a better icon won't also solve the problem as it just won't work on the browser you mentioned for example.

Yeah it doesn't solve the problem, I just told it might be a little more communicative. It would let the users know that the they are about to print the article and would not be taken to any kind of download page (as the download icon suggests). I don't have strong opinions on using it. I was just suggesting it as it might serve as a stopgap.

I can suggest my workaround (that I read somewhere online): We'll measure the system time right after the user taps on the print button. And we'll measure the time again after we call window.print(). We'll then find the difference in measured times. If it's in the milliseconds, we'll assume printing didn't work. If it's more than a second, then we'll assume the printing dialog worked. The reasoning is that window.print() is blocking, and while the print preview is being generated the code after that blocks. When the function doesn't work at all, then the second time we measure will be close to the first one. Once we figure out whether printing worked or not, we can show a toast with a message if printing didn't work, and hide the download button. We can even set a local storage flag to hide the button in subsequent page loads.

Sounds better than not showing anything at all when the print fails. I'm not sure how reliable it would be as there are possibilities of "false" positives where we would be showing the toast even if the print was successful. If it can be done reliably so that false positives are very low, this seems to be the best solution for now.

@bmansurov your workaround will not work, as an example on Samsung S2 calling window.print() tries to create a print preview. The print function doesn't exit immediately.

@pmiazga I thought this is what @bmansurov exactly wants for his solution to work! Am I missing something?

@Kaartic, quoting: bmansurov:

We'll measure the system time right after the user taps on the print button. And we'll measure the time again after we call window.print(). We'll then find the difference in measured times. If it's in the milliseconds, we'll assume printing didn't work."

The way @bmansurov proposed will not work on Galaxy S2 as the second measurement will happen at least couple seconds in the future. Samsung browser on Galaxy S2 does not exit from window.print() immediately like it does in some other browsers which also do not support printing. The Galaxy S2 behavior is pretty strange as it tries to generate the print preview (this is my assumption as it uses 100% cpu after clicking print button), and then it tries to show the print dialog which is not available and it gets back to the page.

@pmiazga, what's the user agent of Galaxy S2's browser? Maybe my proposed solution is good enough for Chrome version 40 and above?

@bmansurov Google Chrome 53.0.2785.124, official build. Android v 4.1.2

The check probably would be Android lower than 4.4 (introduced native printing) or browser lower than v31

I agree, so we need to check both the Android version and Chrome version.

so we talked about Chrome/Chromium itself. Now the question about different browsers which are based on Chromium.

https://en.wikipedia.org/wiki/Chromium_(web_browser) states at least 16 browsers, would be nice to check what those browsers offer, maybe some of them offer better printing experience.

OK, I'll follow up with user agents of those browsers.

Here are the list of user agents of that browsers that are based on Chromium. I've skipped the browsers that don't work on Android, discontinued ones, or the ones aimed at a narrow group of users, i.e. Dartium.

  1. Amazon Silk - http://docs.aws.amazon.com/silk/latest/developerguide/user-agent.html

Mozilla/5.0 (Linux; U; Android 4.4.3; KFTHWI Build/KTU84M) AppleWebKit/537.36 (KHTML, like Gecko) Silk/44.1.54 like Chrome/44.0.2403.63 Mobile Safari/537.36

  1. Brave - https://udger.com/resources/ua-list/browser-detail?browser=Brave

Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_2) AppleWebKit/537.36 (KHTML, like Gecko) brave/0.7.11 Chrome/47.0.2526.110 Brave/0.36.5 Safari/537.36

  1. Opera - http://www.useragentstring.com/pages/useragentstring.php?name=Opera+Mobile

Opera/9.80 (Android; Linux; Opera Mobi/27; U; en) Presto/2.4.18 Version/10.00

It doesn't identify itself as Chrome, and printing doesn't work on it either.

  1. Samsung Internet - http://developer.samsung.com/technical-doc/view.do?v=T000000203

Mozilla/5.0 (Linux; Android 4.4.4; en-au; SAMSUNG SM-N915G Build/KTU84P) AppleWebKit/537.36 (KTHML, like Gecko) Version/2.0 Chrome/34.0.1847.76 Mobile Safari/537.36

  1. Sleipnir - https://udger.com/resources/ua-list/browser-detail?browser=Sleipnir%20Mobile

Mozilla/5.0 (Linux; Android 6.0.1; SO-01G Build/23.5.B.0.303; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/59.0.3071.125 Mobile Safari/537.36 Sleipnir/3.5.5

  1. Yandex Browser - https://udger.com/resources/ua-list/browser-detail?browser=Yandex.Browser%20mobile

Mozilla/5.0 (Linux; Android 4.1.1; xDevice_Note_II_6.0 Build/IMM76D) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.172 YaBrowser/1.0.1364.172 Mobile Safari/537.22

Conclusion
Only Opera doesn't identify itself as Chrome, but printing doesn't work on it either. Other browsers identy themselves as Chrome, but we don't know for sure for which versions printing works. We should check for existence of "Android" and "Chrome" in user agent. Display the download button if Android version is 5.0 or above and Chrome version is 40.0 or above.

We should check for existence of "Android" and "Chrome" in user agent.

Why do we need to check the user agent for Chrome? Can we not rely on window.chrome as we are currently ? If it's not true, that's good as the button will not show.

Display the download button if Android version is 5.0 or above and Chrome version is 40.0 or above.

I'm fine with this. We could even bump to 50 to play safe, given most browsers. I should point out however that we show the button on Chrome OSX as well so we should be careful in the logic relating to Android 5.

I've updated T182059 with all the takeaways here. This seems pretty thorough and a good starting point. Of course the more we check the more edge cases we will find, but I think with T182059 implemented it will be easy to add and change things as we learn more about the world.

Display the download button if Android version is 5.0 or above and Chrome version is 40.0 or above.

@bmansurov I thought you meant version 41 and above as per your following statement. Am I missing something?

However, I manually tested the various Chrome versions on Android and printing didn't work for version 40.0.2214.109. I couldn't test an earlier version (e.g. 39.0.2171.93) on Android 7.1.2 as Chrome kept crashing. Printing worksed on versions 41, 42, 43, 46 (and presumably works on any new version).

Why do we need to check the user agent for Chrome? Can we not rely on window.chrome as we are currently ? If it's not true, that's good as the button will not show.

Because some browsers pass the window.chrome test but printing on them won't work.

@bmansurov I thought you meant version 41 and above as per your following statement. Am I missing something?

Good catch.

bmansurov added a subscriber: bmansurov.

There's a lot to read through here. Is there a tl;dr version where one can check that the AC have been met?

@phuedx I guess I could help you a little.

What is the list of browser that are displaying the download button that are not Chrome?

Covered by T182197#3841513

On these browsers, does the download as PDF button has the same behavior as Chrome?

Covered by T182197#3841513, again.

How can we detect these browsers and remove the button from them?

This is mostly covered by the AC of T182059

Is the inability for the button to work impacted by Android version, i.e. is there an example of a browser running Android 4.4 and above on which the button does not work?

Technically speaking the answer (IIUC) is yes (considering custom ROMs) but as @bmansurov says in T182197#3844780, it's difficult to feature detect "print" and so we take no for the answer (due to the inability).

These answers are from my understanding of the discussion in this task, if I've said something wrong correct me.

@bmansurov I thought you meant version 41 and above as per your following statement. Am I missing something?

Good catch.

Updating T182059 accordingly.

Why do we need to check the user agent for Chrome? Can we not rely on window.chrome as we are currently ? If it's not true, that's good as the button will not show.
Because some browsers pass the window.chrome test but printing on them won't work.

What I meant by this is are there cases where ( !(window.chrome === false) && browserVersion > 41 && chromeInUserAgent(userAgent) ) where the download button does not work? [thanks@kaartic for the edit :)]

@Jdlrobson Just for the sake of clarity, you meant !!window.chrome === false when you said window.chrome === false right ?

What I meant by this is are there cases where ( !(window.chrome === false) && browserVersion > 41 && chromeInUserAgent(userAgent) ) where the download button does not work?

Though I don't know of a browser to meet your requirements. I suspect there's a case in which sniffing for "Chrome" in UA might do the wrong thing. IOW, checking for window.chrome might turn out to be the right thing to do (I'm not 100% sure, though).

In a device running LineageOS 14.1, the stock browser seems to be based on Chrome as it has the User Agent Mozilla/5.0 (Linux; Android 7.1.2; 2014818 Build/NJH47D) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/59.0.3071.92 Mobile Safari/537.36. When I tried to open an English wikipedia article using it, the download icon was not shown. I suspect it's because the window.chrome isn't present in it (I assume the download button is currently shown only when window.chrome is present). I also noted that the "Print" option wasn't shown in the "Share" menu in that browser. So, co-relating the missing "Print" option and the missing window.chromeobject, I theorize that there cases where UA might have "Chrome" but the window.chrome option is missing and the "Print" feature might also be missing. That said, there are possibilities that this theory might be disproved ;-).

[thanks@kaartic for the edit :)]

you're welcome :)

phuedx updated the task description. (Show Details)
phuedx added a subscriber: bmansurov.

🎉🎉🎉

Thanks, @bmansurov, @pmiazga, @Jdlrobson, and @Kaartic for your time and attention!