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

Using ADBKeyboard for injecting text #1751

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

excitoon
Copy link

No description provided.

Copy link
Collaborator

@rom1v rom1v left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the PR 👍

Ideally, I would like the IME code to be included in scrcpy-server: #37 (comment)

Moreover, this would also allow a socket connection between the server and the IME (to minimize latency).

However, until this is implemented (I have zero time to work on this currently), I think calling ADBkeyboard is an acceptable solution.

If this option is passed, I think it should also save the current IME, set the ADBKeyboard IME, and it should restore the previous one on cleanup.

// Process latin keys the same way in order to provide same reaction speed.
try {
Process process = Runtime.getRuntime().exec("am broadcast -a ADB_INPUT_CHARS --eia chars " + String.valueOf((int) c));
return process.waitFor() == 0;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should send the broadcast programmatically (to avoid execute a new process and add latency for every letter).

I guess this involves retrieving an IActivityManager by calling ActivityManager.getService() (by introspection) (or ActivityManagerNative.getService() on older versions), and calling broadcastIntent().

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is that method stable enough? I only have A9 devices and there is something made about activities in A10. I'm not Android developer though.

@@ -651,6 +651,7 @@ guess_record_format(const char *filename) {
#define OPT_DISABLE_SCREENSAVER 1020
#define OPT_SHORTCUT_MOD 1021
#define OPT_NO_KEY_REPEAT 1022
#define OPT_USE_ADB_KEYBOARD 1026
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some numbers don't exist :trollface:

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the PR +1

Ideally, I would like the IME code to be included in scrcpy-server: #37 (comment)

Moreover, this would also allow a socket connection between the server and the IME (to minimize latency).

However, until this is implemented (I have zero time to work on this currently), I think calling ADBkeyboard is an acceptable solution.

If this option is passed, I think it should also save the current IME, set the ADBKeyboard IME, and it should restore the previous one on cleanup.

All of these is right. 👍

@Artur202030
Copy link

https://github.com/Lurker00/scrcpy/releases/tag/v1.10L0
The new features are:
-10-fingers multitouch support.
-Any language input support with an aid of ADBKeyBoard (included).
...

@rom1v
Copy link
Collaborator

rom1v commented Nov 9, 2020

Hi,

I just implemented what I suggested here, and now it works great (without latency).

You could test my work-in-progress branch adbkeyboard.

scrcpy --use-adb-keyboard

What remains to do:

  • automatically select the ADB keyboard on start
  • automatically restore the initial keyboard on stop (even if that won't work if we start 2 instances of scrcpy with ADBKeyboard, since the second one will consider that the initial keyboard was ADBKeyboard).
  • some cleanup

@excitoon
Copy link
Author

excitoon commented Nov 9, 2020 via email

@rom1v
Copy link
Collaborator

rom1v commented Nov 9, 2020

A future next step could be to include the IME in scrcpy (as a real android app), to avoid the requirement to install a separate app.

I'm wondering if it's still possible to create a real/installable android app without gradle (using build-tools directly). The reason is that the official debian package uses build_without_gradle.sh because the full Android SDK is not available in Debian official repositories.

@Artur202030
Copy link

hi,
both English and Russian letters are printed simultaneously.

@rom1v
Copy link
Collaborator

rom1v commented Nov 10, 2020

@Artur202030 Try with:

scrcpy --use-adb-keyboard --prefer-text

@rom1v
Copy link
Collaborator

rom1v commented Nov 10, 2020

An issue with using the existing ADBKeyBoard is the absence of permissions.

As a consequence, once enabled, any installed app could inject any text or events (anything managed by AdbIME) as they like. This is a security issue IMO.

To avoid the problem, the IME should declare a permission, and with shell rights we can send a broadcast with this permission. In short, the equivalent of (not tested):

adb shell am broadcast -a com.com.myexample.MY_ACTION --receiver-permission com.myexample.permission.MY_PERMISSION

Note that this may only work for broadcasts, not services or activities. For these cases (or if the solution above does not work), we could require some shell permission. But it will cause issues for XiaoMI devices: Genymobile/gnirehtet#5 (and gnirehtet may not be started by broadcast receivers Genymobile/gnirehtet@f868180).

@Artur202030
Copy link

Artur202030 commented Nov 10, 2020

@ Artur202030 Попробуйте:

scrcpy --use-adb-keyboard --prefer-text

Sorry your code works without delay

@rom1v
Copy link
Collaborator

rom1v commented Nov 10, 2020

so normal but 1 sec delay

Which branch?

@Artur202030
Copy link

i tested your code and excitoon. Mixed up files.
Sorry.

@rom1v
Copy link
Collaborator

rom1v commented Nov 10, 2020

Could you confirm that there is no delay on my branch (#1751 (comment))?

@Artur202030
Copy link

Could you confirm that there is no delay on my branch (#1751 (comment))?

Your code works without delay.
Thanks.

@quyleanh
Copy link
Contributor

@excitoon could you please take a look at this PR again?

@quyleanh
Copy link
Contributor

quyleanh commented Dec 1, 2020

@rom1v I have built my self adbkeyboard and used scrcpy --use-adb-keyboard, but I still cannot enter Vietnamese character.

Is there any way to report log?

@quyleanh
Copy link
Contributor

@rom1v could you please take a look at this PR?

@rom1v
Copy link
Collaborator

rom1v commented Dec 14, 2020

@quyleanh I implemented broadcasts so that it works without latency (#1751 (comment)), but the absence of permissions of AdbKeyboard is a problem (#1751 (comment)). Also, scrcpy should enable/disable the keyboard on start/stop.

I consider adding a feature to "install" the scrcpy server instead. That way, it could provide its own IME: #1880 (comment)

but I still cannot enter Vietnamese character.

It should allow to inject any UTF-8 chars (try to copy paste a vietnamese character with Alt+Shift+v to inject characters).

@quyleanh
Copy link
Contributor

@rom1v thank you for your kind response.

It should allow to inject any UTF-8 chars (try to copy paste a vietnamese character with Alt+Shift+v to inject characters).

I know that copy paste feature. But I would like to inject UTF-8 characters directly from keyboard.

@quyleanh I implemented broadcasts so that it works without latency (#1751 (comment)), but the absence of permissions of AdbKeyboard is a problem (#1751 (comment)). Also, scrcpy should enable/disable the keyboard on start/stop.

I consider adding a feature to "install" the scrcpy server instead. That way, it could provide its own IME: #1880 (comment)

So in summary, we will not have inject UTF-8 character directly from keyboard soon? As I understand, there are a lot of problem needed to do.

@rom1v
Copy link
Collaborator

rom1v commented Dec 15, 2020

I know that copy paste feature. But I would like to inject UTF-8 characters directly from keyboard.

Yes, I know, but since you said that Vietnamese characters were not injected, I wanted to check where it failed.

There are two copy-paste:

  • once using the clipboard, where any byte stream work (including UTF-8)
  • once injecting the characters, which acts as if every character was pressed from a keyboard (injected char by char), currently it only supports ASCII (+ some other accented chars)

If you use the second method with the ADBKeyboard, I expect that Vietnamese characters work. Is it the case?

@quyleanh
Copy link
Contributor

If you use the second method with the ADBKeyboard, I expect that Vietnamese characters work. Is it the case?

Yes, I use the second method. There are only some Vietnamese characters work.
For example, if I type ô (unicode hex is U+00F4), it is fine. But if I type (unicode hex is U+1ED3), the warning appreases.
[server] WARN: Could not inject char u+1ed3

You can refer to this summary table.

@rom1v
Copy link
Collaborator

rom1v commented Dec 15, 2020

[server] WARN: Could not inject char u+1ed3

You're not running my branch adbkeyboard with scrcpy --use-adb-keyboard: #1751 (comment)

@quyleanh
Copy link
Contributor

You're not running my branch adbkeyboard with scrcpy --use-adb-keyboard: #1751 (comment)

I build your branch and run it now, but I forgot to use scrcpy --use-adb-keyboard syntax.
I checked again with scrcpy --use-adb-keyboard, but I cannot enter any Vietnamese characters now.
How can I provide log since there is no output or warning on terminal?

@rom1v
Copy link
Collaborator

rom1v commented Dec 15, 2020

Try with AdbKeyboard alone: https://github.com/senzhk/ADBKeyBoard (without scrcpy).

@quyleanh
Copy link
Contributor

Thank you for your suggestion but I want to use scrcpy for both mirroring screen and injecting text.
There is no way after all?

@rom1v
Copy link
Collaborator

rom1v commented Dec 15, 2020

Yes, I got it, but try with AdbKeyboard alone to check if Vietnamese characters work. If they don't, then it's expected that the adbkeyboard branch can't do it either. If it works, then there is a problem somewhere else.

@quyleanh
Copy link
Contributor

Thank you for your detail instruction. The senzhk/ADBKeyBoard works well. This is my test:

adb shell am broadcast -a ADB_INPUT_TEXT --es msg 'Hôm nay trời rất là đẹp. Ồ ngoài kia có chú ngựa ô. Ổ gà. Ở nhà không đi học. Hỏi han. Hello?'
Broadcasting: Intent { act=ADB_INPUT_TEXT flg=0x400000 (has extras) }
Broadcast completed: result=0

Is there any other suggestion?

@rom1v
Copy link
Collaborator

rom1v commented Dec 15, 2020

Test with ints:

adb shell am broadcast -a ADB_INPUT_CHARS --eia chars 7891

(7891 is 0x1ed3)

@quyleanh
Copy link
Contributor

It's fine. The result is .

@rom1v
Copy link
Collaborator

rom1v commented Dec 15, 2020

OK so in theory it should work with scrcpy on adbkeyboard. I don't know why it does not, but will not investigate for now, since in the end scrcpy should have its own IME (#1751 (comment)).

@quyleanh
Copy link
Contributor

Actually I have to use an external IME to type and inject Vietnamese on Windows. However other apps are OK with it.
In the previous test, all Vietnamese characters are injected from terminal since I already paste it in adb command. I don't know is there any different between injecting directly from adb command and injecting from other IME.

By the way, I'm glad to hear that you are working on a work around. Could you please push it in this repo, so I can try it? Or if it needs to test, just let me know.

@Helaer
Copy link

Helaer commented Oct 31, 2021

@rom1v Using ADBKeyboard to input text is a good solution, which can solve the problem that Samsung and other devices cannot paste text, Why is there no progress?

@yilksd
Copy link

yilksd commented Jan 10, 2022

I'm using ubuntu 20.04 + fcitx, and I have found 2 problems when using adbkeyboard:
1.adbkeyboard won't stop working when scrcpy window loses focus and I type in a QT application , so the characters also appear in scrcpy . The characters won't appear in scrcpy when I type in Firefox.
2.It seems there is a limitation in string's length. If I type a long sentence , only the first several characters can be injected. There is no such a limitation in adbkeyboard's ADB_INPUT_CHARS feature because I can inject such a long sentence using am broadcast -a ADB_INPUT_CHARS --eia chars 'xxx' , so maybe the limitation is in another place.

@dieskim
Copy link

dieskim commented Sep 9, 2024

@rom1v - I was wondering if there is any update on "scrcpy having its its own IME" ? We tried scrcpy on our current stack and even with "--keyboard=uhid" we are still having clipboard paste issue on Samsung devices etc. Switching keyboard inputs on the device is also needed when switching between languages. In the past we have used Vysor with its own IME and that has been a good solution for different language inputs and clipboard management.

We are happy to put in work to make this happen if thats something that could be helpful? Maybe getting --use-adb-keyboard into the main release could be one way? Or a custom scrcpy IME apk that can be installed?

Thanks for all the work you do.

@rom1v
Copy link
Collaborator

rom1v commented Sep 9, 2024

I was wondering if there is any update on "scrcpy having its its own IME" ?

No, since most of the need is now covered by UHID keyboard.

I understand that there are still issues that UHID keyboard does not solve, but I am not keen on adding a new subproject just for that.

Installing AdbKeyboard can also be a problem for security: any app on the device could inject text (#1751 (comment)).

@dieskim
Copy link

dieskim commented Sep 9, 2024 via email

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.

7 participants