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

[Bug]: Voice input icon should be shown only when corresponding services are available #5698

Open
sivaraam opened this issue Apr 20, 2024 · 12 comments
Labels

Comments

@sivaraam
Copy link
Member

Summary

It's great to see the voice input option in the description and caption elements. There is a possibility that there are no speech-to-text services available on the device. Right now we seem to show the speech-to-text icon even in that case. We should identify this case and avoid showing the icon.

Steps to reproduce

  1. Open the app on a device that does not have speech-to-text services (disabling the existing service should be sufficient)
  2. Initiate an upload
  3. Tap on the speech-to-text icon near the description / caption fields

Expected behaviour

We don't show the speech-to-text icon at all as the same is not available on the device.

Actual behaviour

We show the speech-to-text icon but tapping on the same has no effect.

Device name

OnePlus Nord

Android version

Android 12

Commons app version

main

Device logs

No response

Screen-shots

No response

Would you like to work on the issue?

Prefer not

@sivaraam sivaraam added the bug label Apr 20, 2024
@rohit9625
Copy link
Contributor

I have question, i.e., what is the case or device that doesn't have speech to text feature?

@sivaraam
Copy link
Member Author

I have question, i.e., what is the case or device that doesn't have speech to text feature?

Just try uninstalling / disabling Google's speech-to-text app and other similar apps from your device. Your device would no longer have any of those services.

@rohit9625
Copy link
Contributor

I got it, thanks :)

I guess these two ways can be helpful:-

  1. Change visibility to none after checking if services are available or not.
  2. When tapped on the icon and service is unavailable, then we can ask user to enable or install speech to text services.

@kanahia1
Copy link
Contributor

@rohit9625 How about changing the color of the icon (may be to a Gray) if service is not available, unclicking the icon we can show the Toast to indicate the status of service.

@rohit9625
Copy link
Contributor

@rohit9625 How about changing the color of the icon (may be to a Gray) if service is not available, unclicking the icon we can show the Toast to indicate the status of service.

That's a great idea :)

Let's see @sivaraam's thoughts also.

@nicolas-raoul
Copy link
Member

For now the important thing is probably: How to find out in advance whether service is available or not.

@kanahia1
Copy link
Contributor

Hey @nicolas-raoul, I ran this code (https://stackoverflow.com/a/32596376) I was able to get the engines available

Here are the results

WhatsApp Image 2024-04-21 at 14 17 05_3c703a78

These are the same I got on going to settings of my phone

WhatsApp Image 2024-04-21 at 14 17 05_c76f056b

@sivaraam
Copy link
Member Author

@rohit9625 How about changing the color of the icon (may be to a Gray) if service is not available, unclicking the icon we can show the Toast to indicate the status of service.

I think it might be ideal to just hide the icon altogether when no speech-to-text services are available. I don't see any point with bothering the user about it when their device doesn't have speech-to-text services. If I'm right, the Wikipedia app does the same.

I ran this code (https://stackoverflow.com/a/32596376) I was able to get the engines available

This is good. If it's helpful, this seems like the snippet that the Wikipedia app uses in order to recognize if speech-to-text services are available. We could consider using the same too. if it seems better 🙂

@parneet-guraya
Copy link
Contributor

We have two options here:

1. Reactively update the visibility state for voice input buttons by querying if input service is available or not. In this we have to :

  • query and update while binding views in adapter.
  • query and update in onResume() callback. This is because there's a chance that user might enable/disable service and come back to this screen and would expect updated state of buttons visibility.

The only doubt I have about this approach is how resource intensive it going to be? So in order to query if we a service available or not. We call this method below and this is what it does internally. Call to queryIntentServices is my concern cause it query all the services and filters the one with matching intent passed to it.

   public static boolean isRecognitionAvailable(@NonNull final Context context) {
        // TODO(b/176578753): make sure this works well with system speech recognizers.
        final List<ResolveInfo> list = context.getPackageManager().queryIntentServices(
                new Intent(RecognitionService.SERVICE_INTERFACE), 0);
        return list != null && list.size() != 0;
    }
  • Also, if user have service disabled or not supported on the device, with this approach user might not even know that we have this voice input feature.
  • Not much of a problem but handling state is also another overhead for this. Can lead to bugs too.

2. Keep the buttons as is, check for the availability just-in-time when clicked and if not available just notify user using Toast or Snackbar.

  • With this user will know that app has this feature, it's just their device does not support or it has been disabled.
  • No need to manage state, we always check just-in-time.

Let me know what solution you think would be best and I will create a PR for that.
@nicolas-raoul @sivaraam

@nicolas-raoul
Copy link
Member

I think that checking service availability only once is fine.

If the user enables the service, the user must restart the app.

So it won't be resource-intensive.

I am in favor of not showing anything if the service is not available.

@parneet-guraya
Copy link
Contributor

Okay, just to make sure we're on the same page, this is how it's gonna be ->

  • I'll have a flag lazily initialized based on if the service is available or not, on the startup (in the application class)

  • Let's take a scenario where service was enabled and user disables (probably very few cases) it. But, mic would still show since state doesn't update until next start. In that case does showing Toast/Snackbar make sense, if user try to use it?

Now, for lazy initialization, I can write it in java, since our application class CommonsApplication is in java. But we can use kotlin's lazy {} delegate to keep the code simple.

So, if there's no reason not to, can I migrate application class to kotlin first?

Let me know if my solution is okay. @nicolas-raoul

P.S: I'm sorry if you find it bothering that I'm asking too many question. I try my best not to and figure out stuff on my own :)

@nicolas-raoul
Copy link
Member

I'll have a flag lazily initialized based on if the service is available or not, on the startup (in the application class)

Great idea! :-)

Let's take a scenario where service was enabled and user disables (probably very few cases) it.

No need to consider this case, other than not crashing. Users can understand that if they disable it, it becomes unusable even if the icon is still present.

can I migrate application class to kotlin first?

Sure! Would you mind making it a different pull request? Thanks!

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

No branches or pull requests

6 participants
@nicolas-raoul @sivaraam @rohit9625 @parneet-guraya @kanahia1 and others