operadordecamara / android-bluez-ime

Automatically exported from code.google.com/p/android-bluez-ime
0 stars 0 forks source link

Support keyboard HID input #12

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
This was also sold as by Dell.
Model is XTBT01

Unrooted galaxy tab. I think this doesn't require root?

I've paired the keyboard. I've installed this app. I select the IME, with 
either data dumper or JS1.

Project says only works with JS1, but comments say it works with keyboards. 
Anyway, it comes up with "Error: Connection refused"

I'm using version 1.1 on a galaxy tab, android 2.2

logcat seems to show unhappiness here:

[ 02-12 17:24:34.819 14889:0x3a33 W/BTLD     ] PORT_StartCnf failed result:2
...
[ 02-12 17:24:34.819 19322:0x4bee D/BLZ20_WRAPPER ] btlif_wait_response: 
unblocked fd (-1:36), bta -1, rc 1, wflags 0x100, cflags 0x4, port 0
[ 02-12 17:24:34.819 19322:0x4bee I/BLZ20_WRAPPER ] blz20_wrp_poll: connection 
was rejected
[ 02-12 17:24:34.819 19322:0x4bee D/BLZ20_WRAPPER ] blz20_wrp_poll: set errno 
111 (Connection refused) l.2108
[ 02-12 17:24:34.819 19322:0x4bee D/BluetoothSocket.cpp ] ...connect(36, 
RFCOMM) = -1 (errno 111

Original issue reported on code.google.com by Doug.Cl...@gmail.com on 13 Feb 2011 at 1:59

Attachments:

GoogleCodeExporter commented 8 years ago
I have not had any luck getting any HID based keyboards working.
I saw the comment, but I have no idea what that means.

Form what I understand, the HID profile has to be supported by the Bluetooth 
stack before it can be used. Since HID and RFCOMM are on the same layer in the 
stack, it is not possible to use RFCOMM to read the raw data the device is 
producing. In other words, if the profile is not supported, there is no way to 
get the data from the device.

As far as I can get, this means that as long as the Bleutooth stack on the 
phone does not support HID, no HID based devices will work, regardless of what 
clever code is written in user mode.

Original comment by kenneth@hexad.dk on 13 Feb 2011 at 2:06

GoogleCodeExporter commented 8 years ago
I did some googling, and apparently the @#$(*&^ idiots at Verizon ripped the 
HID profile out of their version of the Samsung Galaxy tab. Other versions have 
it, just not Verizon's. <angry face>

Oh well, thanks anyway!

Original comment by Doug.Cl...@gmail.com on 15 Feb 2011 at 6:41

GoogleCodeExporter commented 8 years ago
Issue 14 has been merged into this issue.

Original comment by kenneth@hexad.dk on 21 Feb 2011 at 10:09

GoogleCodeExporter commented 8 years ago
Issue 13 has been merged into this issue.

Original comment by kenneth@hexad.dk on 21 Feb 2011 at 10:10

GoogleCodeExporter commented 8 years ago
Issue 129 has been merged into this issue.

Original comment by kenneth@hexad.dk on 15 Dec 2011 at 2:43

GoogleCodeExporter commented 8 years ago
Issue 52 has been merged into this issue.

Original comment by kenneth@hexad.dk on 15 Dec 2011 at 2:43

GoogleCodeExporter commented 8 years ago
Issue 128 has been merged into this issue.

Original comment by kenneth@hexad.dk on 15 Dec 2011 at 2:44

GoogleCodeExporter commented 8 years ago
Issue 36 has been merged into this issue.

Original comment by kenneth@hexad.dk on 15 Dec 2011 at 2:47

GoogleCodeExporter commented 8 years ago
I have merged all requests for supporting keyboards into this issue, because 
the work needed to be done is the same.

All the Bluetooth keyboards I know of use the Human Interface Device (HID) 
protocol over Bluetooth.
The main problem with this is that the major manufacturers of Android (HTC, LG, 
Samsung and others) all cripple the Bluetooth stack so it only supports a 
subset of the features found in stock Android (AOSP).
This includes removing support for both HID and the underlying protocol L2CAP.
Their motivation for this seems to be that they only support Bluetooth 
headsets, GPS devices and other similar devices.

It is possible to write a HID layer in user space (i.e. as an app), but it is 
not possible to add L2CAP support without providing a kernel module. Providing 
a kernel module means creating a module that is (possibly) different for each 
device model. And installing the module either requires flashing the phone or 
maybe only rooting it.

The end result is that most people do not have the required software on their 
phone/tablet and are unwilling/unable to do something (drastic), i.e. install a 
custom ROM, to get the software base required.

As I am doing this and other OS projects, my spare time is limited, and the 
time required to get a L2CAP module built that may or may not work on all 
devices is just too big an investment.

Without a solid userbase with L2CAP support, I do not have the incentive to 
spend many hours building the required HID layer, as it is complicated by the 
fact that there are so many different keyboard layouts that needs to be 
supported.

Another demotivating factor is that newer Android (3.2+) supposedly has HID 
support built in, meaning that future Android devices should have keyboard 
support out-of-the-box. That is unless the manufacturer strips it, but then 
they probably strip L2CAP too, and we are back to scratch. 

If anyone has input on how to overcome some of this, let me know.

I am also interrested in reports of people having HID (Keyboard or Wiimote) 
working with a device that has no L2CAP support, such as HTC Sense, Samsung 
Galaxy or LG Thrill. If just one app and one handset supports this, it means 
that it may actually be possible to add L2CAP support without rooting the phone.

Until the situation has changed, and L2CAP is supported on a large number of 
devices, I will not work on this.

If your device has L2CAP support, try this project instead, it should work fine 
with regular Bluetooth keyboards:
http://d.hatena.ne.jp/esmasui/20100330/1269982062

You can also purchase a keyboard app from this company:
http://www.teksoftco.com/

Original comment by kenneth@hexad.dk on 15 Dec 2011 at 3:34

GoogleCodeExporter commented 8 years ago
Issue 2 has been merged into this issue.

Original comment by kenneth@hexad.dk on 16 Dec 2011 at 8:18

GoogleCodeExporter commented 8 years ago
I've changed my mind :).
Attached is a version with Keyboard HID support.
It is not entirely complete, but it works well enough that you can type stuff 
and play a game with it.
If you try this and some key does not work, look at the logcat output, it will 
print some values with the tag "hidkeyboard". Keep pressing the key the does 
not work, and then tell me what symbol is on the keyboard for that key and what 
values you see in logcat, and I will try to add it.

Original comment by kenneth@hexad.dk on 8 Jan 2012 at 8:59

Attachments:

GoogleCodeExporter commented 8 years ago
Hi Kenneth,

sorry I am all new to this.  I have got a HTC Desire HD..  running 2.3.5..  
will the latest bluez work with HID keyboard?  I am getting Unknown Error:0?

thanks,

Wilson

Original comment by wilsonma...@gmail.com on 8 Jan 2012 at 10:30

GoogleCodeExporter commented 8 years ago
Hi.

You are most likely using the stock HTC ROM.
Unfortunately HTC have removed a Bluetooth component calld L2CAP from the 
Android kernel.
Whitout this part of the kernel, you will not get anything based on HID to work.
The only solution is to install a custom ROM, such as Oxygen or CyanogenMOD.

Original comment by kenneth@hexad.dk on 9 Jan 2012 at 7:37

GoogleCodeExporter commented 8 years ago
Since I got the Gingerbread update to my Verizon Galaxy tab, this keyboard now 
"just works". Don't need BluezIME or anything.

Original comment by Doug.Cl...@gmail.com on 27 Jan 2012 at 1:57

GoogleCodeExporter commented 8 years ago
Very cool, that must mean that Samsung are starting to include L2CAP. Lets hope 
the ICS update enables HID for all Samsung Galaxy 2 owners.

Original comment by kenneth@hexad.dk on 29 Jan 2012 at 4:29

GoogleCodeExporter commented 8 years ago
Issue 154 has been merged into this issue.

Original comment by kenneth@hexad.dk on 16 Mar 2012 at 9:19

GoogleCodeExporter commented 8 years ago
I want to use your bluez IMe for HID keyboard Driver, I have 2 questions .
Q1) In futureKeycode class you specify all the keys required by keyboard , but 
still non of them are working .
Q2 ) What classes should i need to include for implementing HID keyboard driver 
? Is that necessary to include session id . 

Thank you for your help .

Original comment by ahmedmeh...@gmail.com on 18 Mar 2012 at 9:20

GoogleCodeExporter commented 8 years ago
Hi, FutureKeycode is just a dump of the Keycodes in Android 4.0.
This is used so I can compile for Android 2.0, but still allow user to send 
KeyPresses that not defined until 4.0.

There is a Keyboard HID Driver?

http://code.google.com/p/android-bluez-ime/source/browse/trunk/BluezIME/src/com/
hexad/bluezime/HIDKeyboard.java

Original comment by kenneth@hexad.dk on 20 Mar 2012 at 8:37

GoogleCodeExporter commented 8 years ago
But it is not working , i have check the logcat , key is received in BluezIME 
but not in the edit text .  

Original comment by ahmedmeh...@gmail.com on 21 Mar 2012 at 9:09

GoogleCodeExporter commented 8 years ago
Ok, but in that case the HID driver is not the problem.

Have you tried plain keys, such as A and B ?
What does logcat say?
What device and ROM are you using?

Original comment by kenneth@hexad.dk on 21 Mar 2012 at 10:15

GoogleCodeExporter commented 8 years ago
Yes i have tried plain keys ,

BluezService --> BluezIMe (Message received in form of key)
But not updating the textfield

I am using Motorola Defy . No idea about the ROM .

Original comment by ahmedmeh...@gmail.com on 21 Mar 2012 at 10:42

GoogleCodeExporter commented 8 years ago
Ok, I assume you are debugging the code.
In BluezIME.java line 349 is where the key is received.
Especially line 388 should reveal what key is being sent.
If the key injection fails, line 393 should report the error.

Does that help you?

Original comment by kenneth@hexad.dk on 21 Mar 2012 at 8:31

GoogleCodeExporter commented 8 years ago
Yes , i have checked that , it is not throwing error . Is that missing 
editorinfo !! To which currently focused edit we are targeting !!

Original comment by ahmedmeh...@gmail.com on 21 Mar 2012 at 11:04

GoogleCodeExporter commented 8 years ago
I don't understand: "Is that missing editorinfo" , is it a question or 
something you have found?
Where did you see this, and why do you think it is wrong?

Original comment by kenneth@hexad.dk on 22 Mar 2012 at 6:42

GoogleCodeExporter commented 8 years ago
I see this in BluezIME class

    public void onStartInputView(EditorInfo info, boolean restarting) {
        super.onStartInputView(info, restarting);

        if (D)
            Log.d(LOG_NAME, "Start input view");

        if (getConnectedCount() != m_prefs.getControllerCount())
            connect();
    }

    @Override
    public void onStartInput(EditorInfo attribute, boolean restarting) {
        super.onStartInput(attribute, restarting);

        // Reconnect if we lost connection
        if (getConnectedCount() != m_prefs.getControllerCount())
            connect();
    }

Original comment by ahmedmeh...@gmail.com on 23 Mar 2012 at 7:31

GoogleCodeExporter commented 8 years ago
first it was connecting with my HId keyboard now i am recieving messages "Error 
: Connection refused"

Logcat is showing this message  : 

03-25 00:28:44.502: E/BluetoothService.cpp(1381): stopDiscoveryNative: D-Bus 
error in StopDiscovery: org.bluez.Error.Failed (Invalid discovery session)
03-25 00:28:44.838: E/BluetoothEventLoop.cpp(1381): event_filter: Received 
signal org.bluez.Adapter:DeviceCreated from /org/bluez/3499/hci0
03-25 00:28:44.838: E/BluetoothEventLoop.cpp(1381): event_filter: Received 
signal org.bluez.Adapter:PropertyChanged from /org/bluez/3499/hci0
03-25 00:28:44.838: E/BluetoothEventLoop.cpp(1381): event_filter: Received 
signal org.bluez.Device:PropertyChanged from 
/org/bluez/3499/hci0/dev_00_16_C1_00_60_D8
03-25 00:28:44.939: D/RfcommReader - hidkeyboard(3709): Failed to connect to 
00:16:C1:00:60:D8, message: java.io.IOException: Connection refused
03-25 00:28:44.939: E/RfcommReader - hidkeyboard(3709): java.io.IOException: 
Connection refused
03-25 00:28:44.955: E/BluezService(3709): java.io.IOException: Connection 
refused
03-25 00:28:46.955: E/BluetoothEventLoop.cpp(1381): event_filter: Received 
signal org.bluez.Device:PropertyChanged from 
/org/bluez/3499/hci0/dev_00_16_C1_00_60_D8
03-25 00:28:46.963: E/BluetoothEventLoop.cpp(1381): event_filter: Received 
signal org.bluez.Adapter:PropertyChanged from /org/bluez/3499/hci0
03-25 00:28:46.978: E/BluetoothEventLoop.cpp(1381): event_filter: Received 
signal org.bluez.Adapter:DeviceRemoved from /org/bluez/3499/hci0
03-25 00:28:52.658: D/dalvikvm(2842): GC_EXPLICIT freed 8365 objects / 338112 
bytes in 76ms
03-25 00:28:55.527: D/SntpClient(1381): request time failed: 
java.net.SocketTimeoutException: Connection timed out 

Original comment by ahmedmeh...@gmail.com on 23 Mar 2012 at 7:34

GoogleCodeExporter commented 8 years ago
But the editorinfo is not used? Or is it used later for something?

Connection refused can be because the PIN has been changed.
You could also try to restart the device.

Original comment by kenneth@hexad.dk on 24 Mar 2012 at 8:36

GoogleCodeExporter commented 8 years ago
I am using your code but i was unable to get shift and caps lock functionality. 
Here is the broadcast receiver which is receiving keys from Bluez service.

    private BroadcastReceiver key3Receiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            int key = Integer.parseInt(intent
                    .getStringExtra(BluezService.COLONY_KEYPRESS_KEY));
            int action = intent.getIntExtra(BluezService.EVENT_KEYPRESS_ACTION,
                    KeyEvent.ACTION_DOWN);
            Log.d("++++ key recieved   ", Integer.toString(key));

            InputConnection ic = getCurrentInputConnection();
            long eventTime = SystemClock.uptimeMillis();

            // ********* Hacks
            if(key==8)
            {
                key=127;
            }

            if (key < 130) {                
                ic.sendKeyEvent(new KeyEvent(eventTime, eventTime, action,COLONYKEYCODE[key],
                        0, COLONYKEYCODE[key], 0, 0, KeyEvent.FLAG_SOFT_KEYBOARD));
            }

        }
    };

can you please help me to achieve this functionality in easier way, your code 
was too complex to understand meta caching. From my Bluetooth keyboard key code 
for caps is 3 and for shift is 2. In the following code what should i pass for 
4th and 6th parameter ? 

ic.sendKeyEvent(new KeyEvent(eventTime, eventTime, action,COLONYKEYCODE[key],
                        0, COLONYKEYCODE[key], 0, 0, KeyEvent.FLAG_SOFT_KEYBOARD));

Original comment by ahmedmeh...@gmail.com on 30 May 2012 at 3:01

GoogleCodeExporter commented 8 years ago
This must be something you added: COLONY_KEYPRESS_KEY, it is not something I 
have put in there.
This seems to be the constructor you are looking at:
http://developer.android.com/reference/android/view/KeyEvent.html#KeyEvent(long,
 long, int, int, int, int)

According to the documentation, you should send KeyCode as param 4 and the meta 
state as param 6.
The meta state is sent by BluezIME as EVENT_KEYPRESS_MODIFIERS, so you get both 
in the event data.
What can be a little bit weird is that you can send CTRL+A, (keycode KEYCODE_A, 
modifiers META_CTRL), but also send CTRL (keycode KEYCODE_META_CTRL, modifiers 
0).

If your keyboard sends different keycodes, you need to intercept them in 
HIDKeyboard.java (or a subclass), it would be hard/impossible to fix it after 
the codes are converted to Android keycode/metastate.

Original comment by kenneth@hexad.dk on 31 May 2012 at 6:40

GoogleCodeExporter commented 8 years ago
thank you , I actually figure it out . Blunder that I was making was that I was 
only setting action KeyEvent.ACTION_DOWN only , and not using 
KeyEvent.ACTION_UP after that for shift key. 

Original comment by ahmedmeh...@gmail.com on 1 Jun 2012 at 6:41