More on the Missing SAF

Last week, I mentioned:




The biggest is that device manufacturers may unilaterally eliminate the Storage Access Framework, by removing or replacing the activities that handle ACTION_OPEN_DOCUMENT and kin. Hopefully, manufacturers will stop doing this, as Android and its apps become more reliant on SAF. However, since Google does not seem to test whether devices support SAF, there is no real pressure for device manufacturers to allow SAF to function.




The link in that quoted section points to an issue that I filed two years ago,
around the time that I wrote my original post about the missing SAF.
I had not received any significant response to that issue��� until this past
Wednesday, when I found out that Google does indeed test SAF.



Sometimes.



So, first, I would like to apologize for mis-interpreting the original lack of response
to my issue and for mis-interpreting the problem.



However, the response to the issue serves as a useful illustration of why we have
compatibility problems despite the Compatibility Test Suite (CTS).





To the best of my knowledge, there is no iCanHazSAF() method, or the equivalent,
anywhere in the Android SDK, to tell us if the device supports the Storage Access
Framework. Similarly, there is no <uses-feature> value for this, the way there
is for app widgets or WebView.



The closest thing that we had is to see if the device supports whatever SAF Intent
action(s) we want to use, such as using resolveActivity() on Intent. If that
returns null, we know that we cannot successfully start that activity. In principle,
some users might not have access to SAF activities due to restricted profile
configuration (e.g., work profiles). So, we should be checking for the availability
of these activities before starting them, just in case.



(in reality, not everyone does this, and I���m as bad as anyone at forgetting to check
these particular Intent actions)



So, from a compatibility standpoint, historically developers were stuck with:





If the SAF Intent actions resolve, assume that the activities work correctly




Hope that devices that do not support the SAF do not export activities that match the SAF Intent
structure





Unfortunately, that second bullet did not hold true in practice, as my SAF issue
points out.





Earlier, I said that Google tests the SAF in the CTS ���sometimes���.
Wednesday���s issue update
states:




These intents have been very thoroughly CTS tested since they were first introduced in Android KitKat, so you can rely on them on all handheld devices. However, certain product teams have decided that these intents are not needed on their products (such as watches and TVs), which is why the tests are skipped on those devices.




It was great to hear that CTS does test the SAF, at least on most
devices. However, the described testing does not quite match what developers need.



Ideally, testing would look like this (using the Google engineer���s terminology for device
types):





On a handheld device, the SAF Intent actions MUST resolve and their activities MUST work




On a watch or TV, the SAF Intent actions MAY resolve, but if they do resolve their activities MUST work





The comment suggests that the testing is more akin to:





On a handheld device, the SAF Intent actions MUST resolve and their activities MUST work




On a watch or TV, ��\_(���)_/��





This is what burns developers on TVs. Some device manufacturers (e.g., Xiaomi)
exported activities matching the SAF Intent structure but without actually allowing
the user to perform SAF actions. This passes the CTS, because the CTS skips these
tests on TV devices. And so we try starting the SAF activities on these broken
devices and get poor results.



I can understand why Google does not want to enforce SAF requirements on watches. I���m
less convinced about the TV argument, and as another issue comment
points out, without SAF on TVs, our ability to access public portions of external
storage is really limited. But I could live with TVs not supporting SAF.
The bigger problem is the fact that there is no clear-cut
way to determine if the SAF is supported on a device and no clear-cut testing to
ensure that devices that claim to support the SAF really do.



If we assume that the statement from the Google engineer is literally true,
then we ���know��� whether SAF is available or not based on hardware type:





android.hardware.type.television = no (even though some devices might actually support it)




android.hardware.type.watch = no




android.hardware.type.automotive = technically ��\_(���)_/��, but you hopefully
are not trying to collect significant user input in this mode anyway




others = technically ��\_(���)_/��, but since there is no explicit hardware type
for handheld devices, we have to treat this as ���yes���





Unfortunately, AFAIK, this is not documented, and we do not know if this is
really what Google wants and what device manufacturers are honoring. Plus, having
the vast majority of devices covered by ��\_(���)_/�� does not inspire confidence.
But, it is probably our best solution right now.





There is no nefarious intent here (not even a nefarious Intent). This is just
another example of edge and corner cases not being covered in specifications,
testing, or both. This sort of thing abounds in software development; this
SAF scenario is far from unique. It���s just that at ���Android scale���, even edge
and corner cases might represent a million users or more. This is why ���Android scale���
compatibility is hard, and why we developers run into problems despite Google���s
best and earnest efforts.

 •  0 comments  •  flag
Share on Twitter
Published on December 08, 2019 05:39
No comments have been added yet.