Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automatically include accessibility stats #59

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

kkostov
Copy link
Collaborator

@kkostov kkostov commented Jan 10, 2025

Fixes #42

  • TelemetryDeck.Accessibility.isBoldTextEnabled - is available on API 31 and above

  • TelemetryDeck.Accessibility.fontWeightAdjustment - is Android only, the value equals 0 if no adjustment is applied

  • TelemetryDeck.Accessibility.isDarkerSystemColorsEnabled

  • TelemetryDeck.Accessibility.fontScale - is Android only

  • TelemetryDeck.Accessibility.isInvertColorsEnabled

  • TelemetryDeck.Accessibility.isVoiceOverEnabled - I kept the name for consistency, but clearly on Android the default service is called TalkBack, alternatives are also possible. The flag returns true if any voice feedback service is enabled.

  • TelemetryDeck.Accessibility.isReduceMotionEnabled

  • TelemetryDeck.Device.isAccessibilityButtonSupported - Android only, true if the accessibility button within the system navigation area is supported.

  • TelemetryDeck.Accessibility.isAudioDescriptionRequested - Android only, true if users want to select soundtrack with audio description by default

  • TelemetryDeck.UserPreference.colorScheme - N/A as devices support various themes and styles. With this PR, isDarkerSystemColorsEnabled returns true if the current theme has dark-mode like features, but the opposite is not necessarily true.

  • TelemetryDeck.Accessibility.isReduceTransparencyEnabled

  • TelemetryDeck.Accessibility.isSwitchControlEnabled

  • TelemetryDeck.Accessibility.preferredContentSizeCategory - N/A as devices support different font styles. TelemetryDeck.Accessibility.fontScale and TelemetryDeck.Accessibility.fontWeightAdjustment have been added to reflect the exact font metrics.

  • TelemetryDeck.Accessibility.shouldDifferentiateWithoutColor - based on accessibility_display_daltonizer_enabled

  • TelemetryDeck.UserPreference.layoutDirection

The README has been updated to include the list above.

@Jeehut @winsmith Please feel free to have a look. Thoughts and comments are always welcome.

@kkostov kkostov marked this pull request as ready for review January 14, 2025 11:00
@Jeehut
Copy link

Jeehut commented Jan 14, 2025

@kkostov Looks good in general, but I'm worried about some fields mismatching the existing naming and therefore creating a need to adjust insights or create new ones. And some need to be removed due to sensitivity.

For example, the following two sound like the same thing for me:

TelemetryDeck.Accessibility.isBoldTextEnabled - is available on API 31 and above
TelemetryDeck.Accessibility.fontWeightAdjustment - is available on API 31 and above, is Android only, the value equals 0 if no custom adjustment is applied

They are both related to font weight. Could you not merge them into one? E.g. by using isBoldTextEnabled on API levels where it's available and falling back to some range you have defined for true for fontWeightAdjustment.

TelemetryDeck.Accessibility.fontScale - is Android only

This sounds very similar to TelemetryDeck.Accessibility.preferredContentSizeCategory on iOS. I already map UICTContentSizeCategoryL etc to just L etc. (XS/S/M/L/XL/XXL/XXXL), maybe you could define font size ranges and map similarly. It's important the default content size categories match so users who don't make any changes are treated the same and the distribution graph doesn't get distorted. AFAIK the default on iOS is L (even though this case is labeled "Medium" in settings). It would make sense to document what category (like L) maps to what range in your README for clarity.

TelemetryDeck.Accessibility.isVoiceOverEnabled - I kept the name for consistency, but clearly on Android the default service is called TalkBack, alternatives are also possible. The flag returns true if any voice feedback service is enabled.

Yeah, that's my bad for not giving a more generic name. But please note that we received feedback from affected users in the community and therefore removed this option anyways, alongside switch control. See TelemetryDeck/SwiftSDK#222.

TelemetryDeck.Device.isAccessibilityButtonSupported - Android only, true if the accessibility button within the system navigation area is supported.

I'm not sure what the accessibility button is, but it sounds similar to "AssistiveTouch" on iOS. Please note that I had considered adding if this setting is enabled but decided against it, because it has no influence on development. There's nothing in UI/UX design a developer needs to consider differently when they have many users having this feature enabled. Users can place it anywhere and might use it for a wide variety of things. From my point of view, there's nothing useful we can learn from it, so we should follow the minimal data principle and not collect it. If this is true for your value as well, consider removing it.

TelemetryDeck.Accessibility.isAudioDescriptionRequested - Android only, true if users want to select soundtrack with audio description by default

I totally missed this, but we have it on iOS as well: UIAccessibility.isVideoAutoDescriptionEnabled. But I think this has the same problem as VoiceOver, causing privacy concerns since you can most certainly identify a disability of a minority and therefore a very sensible type of data. We decided not to track those, so please remove it.

TelemetryDeck.Accessibility.isSwitchControlEnabled

Like I said above, this too is sensitive information, please remove it.

@kkostov
Copy link
Collaborator Author

kkostov commented Jan 14, 2025

Thank you for the fast reply, @Jeehut here are some comments on this:

TelemetryDeck.Accessibility.fontWeightAdjustment

They are both related to font weight. Could you not merge them into one? E.g. by using isBoldTextEnabled on API levels where it's available and falling back to some range you have defined for true for fontWeightAdjustment.

To be clear, fontWeightAdjustment is already used to calculate isBoldTextEnabled (I missed commenting that this is also restricted to API > 31). I can remove it if the exact value is not desired.

TelemetryDeck.Accessibility.fontScale

This sounds very similar to TelemetryDeck.Accessibility.preferredContentSizeCategory on iOS. I already map UICTContentSizeCategoryL etc to just L etc. (XS/S/M/L/XL/XXL/XXXL), maybe you could define font size ranges and map similarly... It's important the default content size categories match so users who don't make any changes are treated the same and the distribution graph doesn't get distorted

I'm not sure a 1:1 mapping produces the expected results, as there is no direct equivalent to content size categories. It's usually a device vendor who chooses the density, resolution, type face and font parameters of the system. If we try to approximate the value to a linear-ish scale, we could get:

Font Scale Range Mapped Category Description
0.0 unspecified An unspecified font size (fallback if unknown).
<= 0.85 extraSmall An extra-small font.
> 0.85 && <= 1.0 small A small font.
> 1.0 && <= 1.15 medium A medium-sized font.
> 1.15 && <= 1.3 large A large font.
> 1.3 && <= 1.5 extraLarge An extra-large font.
> 1.5 && <= 1.75 extraExtraLarge A font that is larger than extra-large but smaller than the largest.
> 1.75 extraExtraExtraLarge The largest font size.

Of course, the caveat is that this is not guaranteed to be always accurate (e.g. on my lab devices, I have a device which defaults to "extraLarge" and another on "medium").

TelemetryDeck.Accessibility.isVoiceOverEnabled, TelemetryDeck.Device.isAccessibilityButtonSupported, TelemetryDeck.Accessibility.isAudioDescriptionRequested, TelemetryDeck.Accessibility.isSwitchControlEnabled

Good catch, will have it removed!

@Jeehut
Copy link

Jeehut commented Jan 14, 2025

@kkostov As we just chatted on Slack, for future reference, here's Claude's summary of my inputs in the chat:

  1. Primary Goal: We should focus on giving developers actionable insights. Specifically, we want to help them understand "what font sizes do I need to test my screen UI with so I'm sure it fits and looks good"

  2. Measurement Approach:

  • What matters is the relative size of the font compared to other UI elements
  • While exact numbers are good, categories mapped to number ranges can be equally useful for insights
  • Having both the calculated category and actual font scale value would be valuable for reference
  1. Testing Recommendations:
  • Focus on covering the most common devices:
    • Google Pixel phones
    • Popular Samsung phones
    • Budget phones (e.g., Xiaomi)
  • Current flagship Samsung and Google phones should have roughly comparable text sizes to similar-sized iPhones
  • Emulators can be used for testing Pixel devices
  • SwiftUI Previews and Jetpack Compose previews could be useful for quick comparisons
  1. Pragmatic Implementation:
  • Aim for covering ~80% of devices with sensible numbers through testing common devices
  • Other hardware manufacturers likely use Samsung and Google as reference points anyway

@kkostov
Copy link
Collaborator Author

kkostov commented Jan 14, 2025

@Jeehut Thanks, but I think I can do better than Claude ;)

In summary, we agreed to send the actual font scale factor as a separate value in addition to a mapping compatible with iOS. The mapping to iOS categories will be done so that "large" corresponds to scale 1.0 in order to align with iOS defaults.

Font Scale Range Mapped Category Description
0.0 unspecified An unspecified font size (fallback if unknown).
<= 0.8 extraSmall An extra-small font.
> 0.8 && < 0.9 small A small font.
>= 0.9 && < 1.0 medium A medium-sized font.
1.0 large A large font.
> 1 && <= 1.3 extraLarge An extra-large font.
> 1.3 && <= 1.5 extraExtraLarge A font that is larger than extra-large but smaller than the largest.
> 1.5 extraExtraExtraLarge The largest font size.

The following is the default font scale (1.0) on a recent One UI Samsung device, it will be mapped to "large". The remaining 5 scale factors will be spread over extraLarge, extraExtraLarge and extraExtraExtraLarge. The 2 smaller factors will be mapped to medium and small. extraSmall would be unused and reserved only for devices which offer an even smaller factor.

image

@Jeehut
Copy link

Jeehut commented Jan 14, 2025

@kkostov There are, in fact, even larger sizes than XXXL on iOS, if I'm not mistaken, that require turning on the accessibility settings. So I could actually alter the implementation on the Swift SDK to accommodate for those as well and maybe those would better map to the 2 even larger sizes you have available here. What do you think?

@kkostov
Copy link
Collaborator Author

kkostov commented Jan 15, 2025

@Jeehut sounds great, let's do this 🚀

@Jeehut
Copy link

Jeehut commented Jan 16, 2025

@kkostov I just checked and we are actually already reporting accessibilities values as well. They report as AccessibilityM, AccessibilityL, AccessibilityXL, AccessibilityXXL, and AccessibilityXXL.

That was not an intended name, but if that works for you, we might want to keep it? Maybe an explanation is needed for developers who don't know that AccessibilityM is actually larger than XXL. But at least the mapping is clear for testing purposes.

An alternative name that keeps the mapping could be XXXL+M, XXXL+L, XXXL+XL, XXXL+XXL, XXXL+XXXL. But I'm not sure if that's any more clear or equally confusing.

@kkostov
Copy link
Collaborator Author

kkostov commented Jan 23, 2025

@Jeehut Could you break this down for me using the actual values to be sent?

For example, based on the above, TelemetryDeck.Accessibility.fontScale would have the value large when font scale equals to 1.0. We also agreed to distinguish 5 additional scale factors for bigger scale: extraLarge, extraExtraLarge, extraExtraExtraLarge, extraExtraExtraExtraLarge and extraExtraExtraExtraExtraLarge.

So your proposal is to rename extraExtraLarge -> AccessibilityM and extraExtraExtraLarge -> AccessibilityL? I'm not sure where the other Accessibility* would come from.

Regarding the XXXL+XXXL notation - I think this is indeed confusing 😅, since we're already working with the artifical mapping of the font scale. I think it will be best to use simple values for the enumeration without overloading them with context, e.g. we shouldn't include the term "Accessibility" in the value since we're already in TelemetryDeck.Accessibility.* and the font scaling (at least on Android) may not be related to accessibility at all. I'm good with "m", "xxxl" or "medium", "large" etc as long as they follow the same progression.

@Jeehut
Copy link

Jeehut commented Jan 23, 2025

@kkostov I do not understand the question, to be honest. But because these names are system given (S to XXXL, and AccessibilityM to AccessibilityXXXL) I think we need to stick to those values so developers can make the connection to the system naming on iOS. If we start mapping say AccessibilityXL to XXXXXL I'm not sure if that's very helpful, then we both need to provide a table.

All that really matters to me is that the default is the same group across platforms, the mapping is not confusing, and the group names are consistent. So, apart from that, what was your question again?

@kkostov
Copy link
Collaborator Author

kkostov commented Jan 23, 2025

@Jeehut I must admit I also don't fully grasp your comment, so let's try to bridge the gap.

Putting aside the OS specifics for a moment. Your request was to create a string enumeration instead of sending fontScale values as a float. So we arrived at the following mapping:

Android fontScale iOS UIContentSizeCategory Signal value for TelemetryDeck.Accessibility.preferredContentSizeCategory
0.0 unspecified unspecified
<= 0.8 extraSmall extraSmall
> 0.8 && < 0.9 small small
>= 0.9 && < 1.0 medium medium
1.0 large large
> 1 && <= 1.3 extraLarge extraLarge
> 1.3 && <= 1.5 extraExtraLarge extraExtraLarge
> 1.5 extraExtraExtraLarge extraExtraExtraLarge

In the comment above, you also want to add AccessibilityM, AccessibilityL, AccessibilityXL, AccessibilityXXL, and AccessibilityXXL. I think if you can fill the table with the correspondingTelemetryDeck.Accessibility.preferredContentSizeCategory for each of these Accessibility* values, I can then adapt the fontScale range to include them and we're good.

@Jeehut
Copy link

Jeehut commented Jan 23, 2025

I can't rate those fontScale numbers. I would expect that you try what values you get with some common devices and than map like this, while using "L" as the default value:

402955727-103a91c0-aaf6-4b9c-965d-01b2829241c2

Other than that, the names sent via parameter should not be long as in medium but short as in M.

The full list: XS, S, M, L, XL, XXL, XXXL, AccessibilityM, AccessibilityL, AccessibilityXL, AccessibilityXXL, AccessibilityXXXL.

I don't think you need "unspecified", given the mapping in the above image, you could simply use XS for anything smaller than whatever your lower-end of the S range is.

I hope it is somewhat clear now.

@kkostov
Copy link
Collaborator Author

kkostov commented Jan 23, 2025

@Jeehut Thank you - all I needed was TelemetryDeck.Accessibility.preferredContentSizeCategory so that's good. I will update the mapping.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Automatically send a11y stats
2 participants