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

Feature: Detect when an Android device is in low power mode and throw an exception from the protocol #343

Closed
steveluscher opened this issue Dec 11, 2022 · 10 comments · Fixed by #363
Labels
enhancement New feature or request javascript Pull requests that update JavaScript/Typescript code

Comments

@steveluscher
Copy link
Contributor

steveluscher commented Dec 11, 2022

Problem

See #335 for the problem statement.

Proposed solution

Detect low power mode, on the client, and throw a typed exception. dApps (and/or the @solana/wallet-adapter can catch this exception and show a message to the user.

Proposed technique

Take advantage of the fact that, in low power mode, an Android browser will refuse to autoplay a video. Presume that low power mode is on unless a shim autoplay video's play event fires.

Reference:

https://github.com/wearemetabolism/browser-system-detect/blob/ed6ca0197c36ac8e1bff61ae707313801c202cd2/index.js#L59-L78

@steveluscher steveluscher added enhancement New feature or request javascript Pull requests that update JavaScript/Typescript code labels Dec 11, 2022
@sdlaver
Copy link
Contributor

sdlaver commented Dec 13, 2022

It'd be good to validate this behavior across different browsers as well, to better understand the scope of the undefined behavior we would be incorporating with this detection method.

@Funkatronics
Copy link
Contributor

I am having some trouble seeing this behavior on my end. Testing on emulators and on my Pixel 3a, it seems the video can always auto play (the 'play' event always fires), regardless of the device being in low power mode. I even tried the "extreme" power mode on my Pixel and it still seems to allow auto play on the web.

@steveluscher
Copy link
Contributor Author

Are you on localhost or on a remote domain as with ngrok? I wonder if the behaviour is domain dependent.

@Funkatronics
Copy link
Contributor

tested both, but now using ngrok and testing with my physical Pixel 3a, so it should effectively simulate a real website

@Funkatronics
Copy link
Contributor

Also, I can test with this handy little website: https://video-dev.github.io/can-autoplay/
or this one: https://googlechrome.github.io/samples/muted-autoplay/index.html

In all cases, autoplay continues to work regardless of the device being in low power mode or not.

@sdlaver
Copy link
Contributor

sdlaver commented Dec 16, 2022

Looks like we might be able to detect when a tab becomes frozen: https://wicg.github.io/page-lifecycle/#freeze-steps

This wouldn't allow us to proactively show an error in the client, but it would allow us to:

  • detect and show the error in the wallet
  • on return to the client, detect that the tab was frozen and no WS connection was made, so cancel the outstanding connection attempt.

@Funkatronics
Copy link
Contributor

@sdlaver Having similar issues with the tab freezing - I am not seeing the window/document enter the frozen state. I am logging the relevant visibility changes and event listeners (according to this doc) and the freeze (and resume) events are not triggered when attempting to connect to the wallet.

The frozen event is only fired when I navigate back and forward on the example web app (the page is frozen and cached, then resumed).

One thing I did notice: when returning to the web after successfully connecting the wallet, the web page enters the active state. Conversely, when returning to the web after failing to connect to the wallet (for any reason, including the user cancelling), the web page enters the passive state. This difference in state seems reliable, but it unfortunately does not tell us much of anything about what actually went wrong. The connection could have failed because of the device being in low power mode, or the user could have just denied/canceled the connection, or some other issue in the wallet or WS server. I think the best we could do with this is display some kind of generic error and link to some kind of help doc: "An unknown error occurred, check out this troubleshooting doc: ..."

@Funkatronics
Copy link
Contributor

@sdlaver what if, when the wallet is launched from the web, we check the device low power mode on the wallet side of things, then displayed an error there? or even returned an error to the web if possible? The native app library would presumably be able to check the Android Power API, and the React Native lib could do something like this to expose the battery status to React?

Its not as nice of a UX as a proactive error, but at least the user would understand why the connection wont work.

@sdlaver
Copy link
Contributor

sdlaver commented Dec 16, 2022

That's what is proposed in #335, and we can certainly do that if there isn't a client-side resolution.

What would be nice is for the client side to be able to detect failures to connect immediately after returning to the dApp. There are cases where a connection can take quite a long time (for e.g., if the Android disambiguation dialog is presented to the user to select their wallet app). The purpose of detecting this case would be to clean up the connection attempt from the client side once we know for certain that the connection will not succeed. The client could use this for some generic "connection failed" handling sooner than the ~90s connection timeout, which we could use to complement wallet-driven UI around reasons for the connection failure (like low-power mode).

@Funkatronics
Copy link
Contributor

Ah yes, must have glossed over your proposed solution there.

We could maybe us this active vs passive state on resume to achieve that? Basically, if the dApp resumes with active state, we could assume that this the case where the wallet successfully connected and returned focus to the web browser. This is not a 100% valid assumption, but at least seems to cover the case where the user tries to connect, but returns to the web because the connection never shows up.

Happy to try out any other possible solutions on the web side of things, but based on the behavior I have seen on my personal device (Pixel 3a), this is active vs passive resume state is the best I have been able to detect so far 😢

@Funkatronics Funkatronics linked a pull request Jan 24, 2023 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request javascript Pull requests that update JavaScript/Typescript code
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants