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

Enable dynamic input switching #97

Closed
utzcoz opened this issue Oct 19, 2018 · 45 comments
Closed

Enable dynamic input switching #97

utzcoz opened this issue Oct 19, 2018 · 45 comments

Comments

@utzcoz
Copy link
Member

utzcoz commented Oct 19, 2018

Hi, @pdsouza , I have done some work to enable dynamic input switching for maruos, but it is split into three projects, so I create a issue to describe it.

Firstly, I add a property called sys.maruos.linux.enable to identify the state whether the desktop is running and remove bluetooth keyboard/mouse filter for Android(vendor_maruos: Enable input dynamic input switching).

Secondly, I remove your patch to filter bluetooth keyboard/mouse in frameworks/native to make InputFlinger work fine as normal, and disable mouse surface in SurfaceFlinger(supports HWC1 and HWC2) which will remove noise view when we use keyboard/mouse in Linux, when desktop is running(frameworks_native: Enalbe dynamic input switching).

And then, I drop all input events except touch screen/navigation/pad events in frameworks/base when desktop is running. It will disable bluetooth/physical keyboard/mouse input events in Android, but Linux will read input events from /dev/input(frameworks_base: Enable dynamic input switching). For touch screen/navigation/pad events, the Linux has disabled it, so it will only work in Android, and it will help stop the desktop when we use Android cast to show desktop.

Lastly, I enhance the PerspectiveService's auto start for public presentation not only HDMI to make PerspectiveService works fine when we use Android cast(frameworks_base: Control desktop state based on public presentation not only HDMI).

I have tested the function, and below is my test steps:

  1. Connect Android phone with bluetooth keyboard/mouse.
  2. Connect Android phone with Android cast to show desktop, and the desktop will auto start when cast is connected, then Android will disable the mouse surface, and Linux will use bluetooth keyboard/mouse correctly.
  3. If I close the Android cast in physical cast device(such as removing the battery) or in Android settings manually with touch screen, the desktop will auto stop and bluetooth keyboard/mouse works normally in Android.
  4. For testing different HWC version, just change TARGET_USES_HWC2 to true for HWC2 and false for HWC1. It works fine in bullhead.

@pdsouza If you think it can help community, I will do real pulling request for it.

Thanks.

@pdsouza
Copy link
Member

pdsouza commented Oct 19, 2018 via email

@pdsouza
Copy link
Member

pdsouza commented Oct 20, 2018

Hi @utzcoz,

I just looked over your changes in detail and it looks good overall!

There is just one issue which is with your addition of the auto-stopping behavior in PerspectiveService: frameworks_base: Control desktop state based on public presentation not only HDMI L#397. I think we can leave the auto-stop behavior out for now, because it is possible that the user wants the desktop to continue running in the background so it is easy to return to to it when the user re-connects to a display. Ideally, we need a Settings option so that users can either enable or disable auto-start and auto-stop behavior - until we have that, we should just leave it running in case there is important work still running on the desktop when the user disconnects. For example, imagine there is a document open that the user has not saved yet - we don't want to shut down until the user explicitly requests it.

Other than that, this is awesome. Please go ahead and send me the pull requests for each project and we can work together to get your work merged in for the next release.

Thanks!

@utzcoz
Copy link
Member Author

utzcoz commented Oct 20, 2018

@pdsouza I got your concerns. I will remove auto-stop from patch. But for bluetooth/physical mouse/keyboard working in Android when disconnecting HDMI or Android cast, I need move the code to change sys.maruos.linux.enable based on desktop state from vendor/maruos to frameworks/base that needs some time. After working and testing, I will do real request of all patches directly and notify you in this issue.

Lastly, thanks for your review.

@utzcoz
Copy link
Member Author

utzcoz commented Oct 20, 2018

@pdsouza If we let desktop running when we disconnect HDMI or Andoird cast, it will read input events from /dev/input always, what if we use bluetooth/physical mouse/keyboard in Android, which will make noise for desktop. For context-saveing, why don't we use lxc-freeze and lxc-unfreeze, what also exist in liblxc ? It will also help decrease one setting item(whether user want to auto-stop when disconnect HDMI or Android cast).

Thanks.

@pdsouza
Copy link
Member

pdsouza commented Oct 20, 2018

@utzcoz Oh, I see what you mean. Now that Android can use BT devices it will create noise on the desktop side. Thanks for bringing this up, I forgot about that.

I think lxc-freeze is a good option, but it will not fit the use-case where users keep the desktop running in the background in headless mode, for example to use SSH or to run as a server. We still need to let users run the processes on the desktop in non-interactive mode.

Proposal v2

Ideally, we need a way to dynamically switch input events on both Android and the desktop container depending on whether the desktop is in interactive or headless mode (display available or no display available, respectively).

@utzcoz's work implements dynamic input switching on Android already, but we need to figure out how to do dynamic input switching within Linux too. Otherwise, we must either shutdown or freeze the desktop to prevent noise from /dev/input - this is not acceptable because some users may want to run the desktop in headless mode.

Here is one idea to implement dynamic input switching on the desktop:

PerspectiveService can tell the desktop container to use or ignore input events depending on which mode (headless or interactive). One way to do this would be to have PerspectiveService run a command within the desktop container via lxc-attach that can mask /dev/input somehow. And when a display is added, PerspectiveService can run a command in the container to unmask /dev/input.

To do this:

  1. Add a property sys.maruos.desktop.interactive similar to @utzcoz's sys.maruos.linux.enable property as a flag to check whether the desktop is running in interactive or headless mode. All we need to do is change the property name in @utzcoz's patches.

  2. Add a function enableInput(true|false) to LXCContainerManager to switch on/off input within desktop by running lxc-attach to run some command (maybe a script on the desktop that can use udev or xinput to dynamically mask/unmask input events within Linux).

  3. When the desktop mode changes from interactive to headless or vice versa (due to external display being added or removed), PerspectiveService will set sys.maruos.desktop.interactive = true|false and call enableInput(true|false) to switch input on or off within the desktop container.

I can help implement the dynamic input switching within the desktop container. Then we can use both of our patches together to solve this problem.

@utzcoz
Copy link
Member Author

utzcoz commented Oct 20, 2018

@pdsouza Thanks for your solution, and it looks good to me. I will use your proposal to modify my patch to let it clear the input noise aon desktop side.

@utzcoz
Copy link
Member Author

utzcoz commented Oct 23, 2018

@pdsouza I have done some work to implement your proposal, and below is my implement steps.

Firstly, I rename the property sys.maruos.linux.enable to sys.maruos.desktop.interactive in fraemworks/native(frameworks_native: Rename sys.maruos.linux.enable to sys.maruos.desktop.interactive).

Then, I remove directly auto-stop from PerspectiveService(frameworks_base: Remove directy auto-stop from PerspectiveService).

Thirdly, I rename property name in frameworks/base and add enableInput interface in frameworks/base(Notify desktop to disable/enable input when display state changed).

And then, I remove property changing logic from vendor/maruos and add enableInput interface and its implementation in vendor/maruos(vendor_maruos: Notify desktop disable/enable input when display state changed). Also, I add lxc-attach to Android for debug usage(vendor_maruos: Add lxc-attach to Android to debug usage). The lxccontainer.attach_run_wait uses execvp to do real executing, so the lxccontainer.attach_run_wait's argv must include be the program in argv[0] and include NULL in last item.

Lastly, I add real script in container to enable/disable input dynamic based on xinput(blueprints: Enable dynamic input switching). The lxc-attach executes commands as root user, which can't access xserver default. So I export DISPLAY and XAUTHORITY from first user(uid is 901000 defined in blueprints/blueprints/debian/debpkg/etc/adduser.conf). I know it's not a good habit to use magic number, but I don't have a better idea. Sorry.

After above work, when I disconnect the Android cast, the desktop will still run background, and the bluetooth keyboard/mouse won't make noise in desktop. After reconnecting, the bluetooth keyboard/mouse work correctly in desktop again as normal.

For testing noise, I open a terminal in desktop, and change input focus on it, and then disconnect Android cast and use keyboard to input some characters. If the patch works correctly, the terminal will stay the state as before after reconnecting, otherwise your characters will add on terminal.

Thanks.

@pdsouza
Copy link
Member

pdsouza commented Oct 25, 2018

@utzcoz Thanks! I will do a detailed review and get back to you soon!

@pdsouza
Copy link
Member

pdsouza commented Oct 27, 2018

OK, I just read through all the patches.

This looks really good. Just one edge case I think: what happens if the user starts the desktop manually (via Settings > Desktop > Dashbboard) in the background when no display is attached? In this case, it looks like input will still be enabled since the hook to disable input only happens if a display is removed (https://github.com/utzcoz/android_platform_frameworks_base/commit/be0b4f2ec204e6cd5bf8cab59c98dab0beaf3d5a#diff-85fab8f12f3a3954e15f12dedcd4b711R421). We need to check if a display is available when the user starts and disable input if no display is attached. Please correct me if I am wrong and you already handle this case.

Once that's fixed, this should be good to go and you can send me the PRs! Thanks again for all the great work @utzcoz!

@utzcoz
Copy link
Member Author

utzcoz commented Oct 27, 2018

@pdsouza You're correct. I will add another patch to fix it. Thanks for your detailed review.

@utzcoz
Copy link
Member Author

utzcoz commented Oct 28, 2018

@pdsouza I add a patch to support dynamic input switching for desktop running without public presentation(frameworks_base: Add public presentation connecting check for dynamic input switching). So now the logic to enable/disable dynamic input is:

  1. Start/Stop desktop without public presentation, the input is disabled for Linux, and enabled for Android.
  2. Start desktop with public presentation, the input is disabled for Android, and enabled for Linux. And if you disconnect the public presentation, the input will be disabled for Linux, and enabled for Android.
  3. Start desktop with public presentation, the logic is the same as case 2. But if you disconnect desktop with setting, and don't disconnect the public presentation, the LXC will stop, so every thing will work fine.

There is a missed occasion that starting desktop without public presentation, and connect public presentation later. With my nexus 5x and Android cast device(not ChromeCast), if I start desktop without public presentation firstly, and then try to connect my Android cast device, it is failed. Logically, my patches will not affect public presentation's display, so I guess it's my Android cast device's problem. If it works fine in this occasion with ChromeCast, I will send the PRs; if not, maybe we can discuss the detail of bug.

Thanks.

@utzcoz
Copy link
Member Author

utzcoz commented Oct 28, 2018

For testing input status, I add a script into Linux, and use lxc-attach to run it. Below is script content:

uname=$(/usr/bin/getent passwd 901000 | /usr/bin/cut -f1 -d:)
export DISPLAY=:0.0
export XAUTHORITY=/home/$uname/.Xauthority
ids=$(/usr/bin/xinput list --id-only)
for id in $ids;do /usr/bin/xinput list-props $id;done

@pdsouza
Copy link
Member

pdsouza commented Oct 28, 2018

@utzcoz Looks good to me!

There is a missed occasion that starting desktop without public presentation, and connect public presentation later. With my nexus 5x and Android cast device(not ChromeCast), if I start desktop without public presentation firstly, and then try to connect my Android cast device, it is failed.

The cast issue is strange. Do you mean the device fails to connect to the cast device in this case? I agree that your patches should not affect cast though...there must be a bug somewhere else. Can you try reproducing without your patches to be sure? If it is not related to your patches, maybe we can create a separate issue to debug?

@utzcoz
Copy link
Member Author

utzcoz commented Oct 29, 2018

@pdsouza I have sent all patches with four PRs for sign-off and building checking:

  1. frameworks_base: Enable dynamic input switching.
  2. frameworks_native: Enable dynamic input switching.
  3. vendor_maruos: Enable dynamic input switching.
  4. blueprints: Enable dynamic input switching.

I will do more detailed testing for the cast issue. If it is my patch problem, I will try to fix it and append patch to current PR; otherwise I will create a new issue to describe it.

Thanks.

@utzcoz utzcoz changed the title [Pull Request]Enable dynamic input switching Enable dynamic input switching Oct 29, 2018
@utzcoz
Copy link
Member Author

utzcoz commented Oct 29, 2018

Hi @pdsouza, I use repo sync forall -c "git reset --hard" and repo sync -c to reset and sync source code, and then test the cast. The problem exists too. For this problem, I will create a another issue to describe it. Maybe we can do a final code-review for above four PRs.

Thanks.

@pdsouza
Copy link
Member

pdsouza commented Oct 29, 2018

@utzcoz OK thanks. I'll review the PRs soon and we can create a separate issue for cast.

@pdsouza
Copy link
Member

pdsouza commented Oct 29, 2018

@utzcoz I have reviewed each PR. Two of them are good and two of them need a little bit more work. Please see my review for details.

I realized that these PRs touch almost every critical component of Maru except mflinger/mclient. Great job reading all the source code and getting this done - I am impressed! Just a few little fixes and I will merge!

@utzcoz
Copy link
Member Author

utzcoz commented Nov 1, 2018

@pdsouza I have fixed the problem, and squashed commits to a main commit for cleaning up, which I think will make commit message clean and readable. I remove /lib/udev/rules.d/80-net-setup-link.rules for testing temporarily.

Also I test again, below is my test steps:

  1. Start the desktop from setting, and input is disabled for the desktop and enabled for Android.
  2. Connect to Android cast when the desktop is running in background, and input is enabled for desktop and disabled for Android.
  3. Disconnect the Android cast, and the desktop is running in background, and input is disabled for the desktop and enabled for Android.
  4. Stop the desktop, and everything runs as normal.
  5. Connect the Android cast, and the desktop is started, and input is enabled for the desktop and disabled for Android.
  6. Disconnect the Android cast, it returns to step 3.

I use above script to use xinput to check input state.

Thanks.

@pdsouza
Copy link
Member

pdsouza commented Nov 3, 2018

@utzcoz Thanks for resolving the issues. I will run some test builds with these patches to verify since this is an important change.

@pdsouza
Copy link
Member

pdsouza commented Nov 5, 2018

@utzcoz Just tested with my Nexus 5X and it works great! I am going to test on the Nexus 5 as well just to make sure everything is working well on older hw libs (hwcomposer especially) and with HDMI, but I expect it to be good.

Edit: I tested the 5X using Chromecast and there was no issue connecting to Chromecast again even while the desktop was running in the background. So it appears that the Chromecast does not have the same issue as your cast device. We will still fix your cast issue though.

@pdsouza
Copy link
Member

pdsouza commented Nov 5, 2018

@utzcoz I found two issues while testing my Nexus 5X some more.

  1. The "back" software button on Android does not work when input is enabled for the desktop. Maybe it is somehow falling into your check in ViewRootImpl?

  2. If you stop the desktop manually in Settings while public presentation display is connected, and then start it again manually in Settings (with the display still connected), the input will still be enabled for Android and disabled for the desktop...but it should be enabled for the desktop and disabled for Android. I think it is because of this line in PerspectiveService. I think we need to change it to updateDesktopInteractiveStateInternal(mDisplayLister.isPublicPresentationConnected()); so that when the user manually starts the desktop, we set the interactive state correctly even if the user does not add or remove a display.

@utzcoz
Copy link
Member Author

utzcoz commented Nov 6, 2018

@pdsouza I have fixed the problem.

  1. The back software button is not from touch screen, so old logic drops it. I start to use whether the input event is from external device to determine whether we should drop it.

  2. I'm sorry for my mistake of missing this occasion.

@pdsouza
Copy link
Member

pdsouza commented Nov 6, 2018

@utzcoz Thanks for the quick response! I will build and test the new patches on the 5X again and get back to you soon.

@pdsouza
Copy link
Member

pdsouza commented Nov 6, 2018

@utzcoz Great, looks like both issues are fixed! I will run a build for the Nexus 5 and do a quick test on that.

@pdsouza
Copy link
Member

pdsouza commented Nov 7, 2018

@utzcoz On the Nexus 5, it looks like the native call to enableInput fails:

11-06 20:32:08.091   285   349 D perspectived: running enableInput(true)...
11-06 20:32:08.122   528   690 W PerspectiveService: Update desktop interactive state failed

This causes noise on the desktop.

I tried running /etc/maruos/enable-input and /etc/maruos/disable-input from within the desktop itself and it worked. So maybe something is going wrong with the lxc-attach command on 32-bit / armhf systems? I wonder if it is maybe a kernel issue?

I tried to debug by running lxc-attach directly on the command line:

hammerhead:/ # lxc-attach --name=default -- /bin/bash -c /etc/maruos/disable-input
lxc_container: external/lxc/src/lxc/attach.c: lxc_attach_to_ns: 279 No such file or directory - failed to open '/proc/3006/ns/pid'
lxc_container: external/lxc/src/lxc/attach.c: lxc_attach: 1011 failed to enter the namespace

I discovered that the PID namespace file does not exist in procfs for the container (pid 3006):

hammerhead:/ # ls -al /proc/3006/ns/                                         
total 0
dr-x--x--x 2 root root 0 2018-11-06 20:32 .
dr-xr-xr-x 8 root root 0 2018-11-06 20:32 ..
lrwxrwxrwx 1 root root 0 2018-11-06 20:38 ipc -> ipc:[4026534309]
lrwxrwxrwx 1 root root 0 2018-11-06 20:32 mnt -> mnt:[4026534307]
lrwxrwxrwx 1 root root 0 2018-11-06 20:32 net -> net:[4026533494]
lrwxrwxrwx 1 root root 0 2018-11-06 20:38 uts -> uts:[4026534308]

I think this is due to this kernel patch I had to apply to fix building PID namespaces on hammerhead.

If I run lxc-attach without entering the PID namespace, it works (the X errors appear to be harmless):

hammerhead:/ # lxc-attach --name=default --namespaces="MOUNT|IPC|UTSNAME" -- /bin/bash -c /etc/maruos/disable-input
X Error of failed request:  BadAccess (attempt to access private resource denied)
  Major opcode of failed request:  131 (XInputExtension)
  Minor opcode of failed request:  57 ()
  Serial number of failed request:  20
  Current serial number in output stream:  21
...

I can also run /etc/maruos/enable-input with no issues the same way.

I guess I will have to get PID namespaces working on hammerhead to prevent this issue.

For devices with older kernels that do not support PID namespaces like hammerhead, perhaps we can set the namespaces flag in lxc_attach_options_t to drop the PID namespace.

I will try to fix the PID namespaces in the hammerhead kernel first though. I will hold merging the patches until I work on getting PID namespaces to compile in the hammerhead kernel and then test this again.

Thanks for your patience on getting these patches merged in!

@pdsouza
Copy link
Member

pdsouza commented Nov 7, 2018

@utzcoz No luck on patching the hammerhead 3.4 kernel to have a working proc for PID namespaces with a few hours of work... We also support the Nexus 7 2013 (flo) which also uses an older 3.4 kernel. These older devices won't be able to use lxc-attach with the PID flag.

I may still be able to really dig down and see what's wrong in the kernel at some point but I don't have the time right now. Using a workaround until that happens is probably the best solution to get your patches in ASAP.

For now, can we try to drop the PID flag in lxc_attach_options_t so we can still use this with older kernels?

@utzcoz
Copy link
Member Author

utzcoz commented Nov 8, 2018

@pdsouza I have added a new patch to drop PID namespace, and pushed it to PR. I have tested it with Nexus 5X, but I don't have a Nexus 5, so maybe you can test it with Nexus 5 to check whether it works fine.

Thanks.

@pdsouza
Copy link
Member

pdsouza commented Nov 9, 2018

@utzcoz Tested on the Nexus 5 and it now works! We should be able to still support older devices now. Thanks for the quick patch.

I noticed one more thing that may be confusing to users: when the desktop is in interactive mode (input enabled), the phone's virtual keyboard does not show up, so the user cannot type while the desktop is interactive unless they tap the keyboard icon in the system button tray at the bottom (or go to Settings > System > Languages & input) and select "Show virtual keyboard". We also need to set the virtual keyboard to disable "Show correction suggestions". We need to look into whether there is a config option that can be set to enable these settings by default - or, ideally, to enable the virtual keyboard when the desktop is interactive, and then disable it when it is not. Do you have any ideas on how to do this? I can help take a look at this too.

I also noticed that one nice side-effect of your patches is that the phone's display (and presentation display) will be prevented from sleeping when the user is interacting with the desktop. It works really nicely when the phone is connected to power and Daydream is enabled.

To sum it up: your patches are good! I'm just going to hold them till we get the virtual keyboard fixed.

@pdsouza
Copy link
Member

pdsouza commented Nov 9, 2018

@utzcoz I did some digging and I found out how the Settings app is enabling the virtual keyboard even when a hard (physical) keyboard is attached. The Settings keyboard fragment calls InputMethodUtils to set the system preference Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD.

Maybe we can toggle this setting "ON" when the desktop is in interactive mode?

@utzcoz
Copy link
Member Author

utzcoz commented Nov 10, 2018 via email

@utzcoz
Copy link
Member Author

utzcoz commented Nov 10, 2018

@pdsouza I add a new patch to force showing IME when desktop is interactive(maruos/android_platform_frameworks_base@a26f43c).

Test steps:

  1. Normally, the IME is showing when I try to enter url in browser.
  2. Then I connect the bluetooth keyboard, and the IME is disabled when I try to enter url in browser, but I can use bluetooth keyboard to enter url in browser.
  3. And next, I connect the Android cast, the bluetooth keyboard is redirected to desktop because of before patches, and the IME is showing when I try to enter url in browser.

Thanks.

@utzcoz
Copy link
Member Author

utzcoz commented Nov 10, 2018

I also noticed that one nice side-effect of your patches is that the phone's display (and presentation display) will be prevented from sleeping when the user is interacting with the desktop. It works really nicely when the phone is connected to power and Daydream is enabled.

@pdsouza For this nice-side-effect, I think it is because of we just drop input events in top level(frameworks/base), and don't remove input devices in low level(inputflinger), which will make Android still active.

@pdsouza
Copy link
Member

pdsouza commented Nov 10, 2018

@utzcoz Just tested on the 5X and the IME patch works great! I will do a final test on the Nexus 5 and this should be good to merge. Thank you for patching this so quickly!

For this nice-side-effect, I think it is because of we just drop input events in top level(frameworks/base), and don't remove input devices in low level(inputflinger), which will make Android still active.

Yeah, this is definitely the right way to do input in Maru. Thanks for indirectly fixing this as well!

@pdsouza
Copy link
Member

pdsouza commented Nov 11, 2018

@utzcoz Tested on the Nexus 5 and all is good.

I just merged in all your PRs. Thank you so much for your effort and time to make dynamic input switching happen for Maru!

@utzcoz
Copy link
Member Author

utzcoz commented Nov 11, 2018

@pdsouza Thanks.

@utzcoz utzcoz closed this as completed Nov 11, 2018
@oscarvalenzuelab
Copy link

Hi,

Do we have a RC or binary image that include this fix?
The last release was published on Jun 3, 2017.

Thanks,
Oscar.

@pdsouza
Copy link
Member

pdsouza commented Nov 26, 2018

@oscarvalenzuelab Yes, apologies for no official releases for a while. We haven't made an official release since Maru 0.4 as we were transitioning from Android 6 to Android 8 over the past year and had some changes in project management, but we are back in action now.

You can find our test builds for Maru 0.6 (not yet officially released) here: https://github.com/maruos/builds/releases. This particular patch will be available in the next build (0.6.3) which should be out by the end of the week.

@oscarvalenzuelab
Copy link

Yes I saw that, but no build for -flo :(

@pdsouza
Copy link
Member

pdsouza commented Nov 27, 2018

@oscarvalenzuelab Yes, sadly flo's /system partition is too small to support Maru according to our N7 maintainer @TMartinPPC... I hope we can figure out a workaround for this at some point, but the focus is on newer devices now.

@oscarvalenzuelab
Copy link

Any plan on porting just this change?

@utzcoz
Copy link
Member Author

utzcoz commented Nov 28, 2018

@pdsouza Maybe it's time to move the rootfs management to a app like Samsung's Linux on Dex. If we can do it, the system image's size is not a problem to port maruos. Also it's a good start to make maruos as a app.

@pdsouza
Copy link
Member

pdsouza commented Nov 28, 2018

@utzcoz Yes, that's the right solution here. This has been discussed on our forum for a while now and @dianaxxyyzz is looking into possibly prototyping a simple app for installing the desktop image. I've created an issue for it for further discussion: #99.

@utzcoz
Copy link
Member Author

utzcoz commented Dec 16, 2018

@dianaxxyyzz I will test it.

@utzcoz
Copy link
Member Author

utzcoz commented Apr 1, 2019

@dianaxxyyzz I have fixed the ESC response problem in PR Disable unhandled key when desktop is interactive. Also, it will help to fix the problem the Android responses to shortcut, such as ALT + TAB for app switching. Maybe you can sync the latest code to verify it. Thanks.

@utzcoz utzcoz closed this as completed Apr 1, 2019
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

No branches or pull requests

4 participants
@pdsouza @oscarvalenzuelab @utzcoz and others