223 lines
5.9 KiB
Java
223 lines
5.9 KiB
Java
package keepass2android.plugin.inputstick;
|
|
|
|
import java.util.ArrayList;
|
|
|
|
import android.app.AlertDialog;
|
|
import android.app.Service;
|
|
import android.content.Intent;
|
|
import android.content.SharedPreferences;
|
|
import android.os.AsyncTask;
|
|
import android.os.IBinder;
|
|
import android.preference.PreferenceManager;
|
|
import android.util.Log;
|
|
import android.widget.Toast;
|
|
|
|
import com.inputstick.api.ConnectionManager;
|
|
import com.inputstick.api.InputStickStateListener;
|
|
import com.inputstick.api.basic.InputStickHID;
|
|
import com.inputstick.api.basic.InputStickKeyboard;
|
|
import com.inputstick.api.hid.HIDKeycodes;
|
|
import com.inputstick.api.layout.KeyboardLayout;
|
|
|
|
public class InputStickService extends Service implements InputStickStateListener {
|
|
|
|
private class ItemToType {
|
|
public String mText;
|
|
public String mLayout;
|
|
public String mParams;
|
|
|
|
ItemToType(String text, String layout, String params) {
|
|
mText = text;
|
|
mLayout = layout;
|
|
mParams = params;
|
|
}
|
|
|
|
public void type() {
|
|
typeString(mText, mLayout, mParams);
|
|
}
|
|
}
|
|
|
|
private ArrayList<ItemToType> items = new ArrayList<ItemToType>();
|
|
|
|
private static final String _TAG = "KP2AINPUTSTICK";
|
|
public static final String DISCONNECT = "disconnect";
|
|
public static final String TYPE = "type";
|
|
|
|
@Override
|
|
public void onCreate() {
|
|
InputStickHID.addStateListener(this);
|
|
super.onCreate();
|
|
}
|
|
|
|
@Override
|
|
public int onStartCommand(Intent intent, int flags, int startId) {
|
|
|
|
if (intent != null)
|
|
Log.d(_TAG, "starting with "+intent.getAction());
|
|
else
|
|
Log.d(_TAG, "starting with null intent");
|
|
|
|
if (DISCONNECT.equals(intent.getAction())) {
|
|
Log.d(_TAG, "disconnecting");
|
|
try {
|
|
int state = InputStickHID.getState();
|
|
switch (state) {
|
|
case ConnectionManager.STATE_CONNECTED:
|
|
case ConnectionManager.STATE_CONNECTING:
|
|
case ConnectionManager.STATE_READY:
|
|
InputStickHID.disconnect();
|
|
break;
|
|
case ConnectionManager.STATE_DISCONNECTED:
|
|
case ConnectionManager.STATE_FAILURE:
|
|
break;
|
|
default:
|
|
InputStickHID.disconnect();
|
|
}
|
|
} catch (NullPointerException e) {
|
|
Log.d(_TAG, "couldn't disconnect. Probably we never connected.");
|
|
}
|
|
|
|
stopSelf();
|
|
return Service.START_NOT_STICKY;
|
|
}
|
|
|
|
if (TYPE.equals(intent.getAction())) {
|
|
int state = InputStickHID.getState();
|
|
String stringToType = intent.getStringExtra(Const.EXTRA_TEXT);
|
|
String layoutToUse = intent.getStringExtra(Const.EXTRA_LAYOUT);
|
|
String params = intent.getStringExtra(Const.EXTRA_PARAMS);
|
|
//Toast.makeText(this, "type params: "+params, Toast.LENGTH_LONG).show();
|
|
//Log.d(_TAG, "type params: "+params);
|
|
|
|
switch (state) {
|
|
case ConnectionManager.STATE_CONNECTED:
|
|
case ConnectionManager.STATE_CONNECTING:
|
|
synchronized (items) {
|
|
items.add(new ItemToType(stringToType, layoutToUse, params));
|
|
}
|
|
break;
|
|
case ConnectionManager.STATE_READY:
|
|
typeString(stringToType, layoutToUse, params);
|
|
break;
|
|
case ConnectionManager.STATE_DISCONNECTED:
|
|
case ConnectionManager.STATE_FAILURE:
|
|
synchronized (items) {
|
|
items.add(new ItemToType(stringToType, layoutToUse, params));
|
|
}
|
|
Log.d(_TAG, "trigger connect");
|
|
InputStickHID.connect(getApplication());
|
|
|
|
break;
|
|
}
|
|
}
|
|
return Service.START_NOT_STICKY;
|
|
|
|
}
|
|
|
|
private void typeString(String stringToType, String layoutToUse, String params) {
|
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
|
int reportMultiplier = 1;
|
|
try {
|
|
reportMultiplier = Integer.parseInt(prefs.getString("typing_speed", "1"));
|
|
} catch (Exception e) {
|
|
reportMultiplier = 1;
|
|
}
|
|
|
|
if (params != null) {
|
|
//override typing speed
|
|
if (params.contains(Const.PARAM_SLOW_TYPING)) {
|
|
reportMultiplier = 10;
|
|
}
|
|
}
|
|
|
|
InputStickHID.setKeyboardReportMultiplier(reportMultiplier);
|
|
|
|
if (InputStickHID.getState() == ConnectionManager.STATE_READY) {
|
|
//Log.d(_TAG, "typing "+stringToType + " @ " + layoutToUse + " @mul: " + reportMultiplier);
|
|
if (stringToType.equals("\n")) {
|
|
InputStickKeyboard.pressAndRelease(HIDKeycodes.NONE, HIDKeycodes.KEY_ENTER);
|
|
return;
|
|
} else if (stringToType.equals("\t")) {
|
|
InputStickKeyboard.pressAndRelease(HIDKeycodes.NONE, HIDKeycodes.KEY_TAB);
|
|
return;
|
|
} else {
|
|
KeyboardLayout l = KeyboardLayout.getLayout(layoutToUse);
|
|
l.type(stringToType);
|
|
}
|
|
} else {
|
|
Log.d(_TAG, "typing NOT READY");
|
|
}
|
|
InputStickHID.setKeyboardReportMultiplier(1);
|
|
}
|
|
|
|
private void typeQueue() {
|
|
synchronized (items) {
|
|
for (ItemToType itt : items)
|
|
{
|
|
Log.d(_TAG, "typing (after callback) " + itt.mText);
|
|
itt.type();
|
|
}
|
|
items.clear();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public IBinder onBind(Intent arg0) {
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
public void onDestroy() {
|
|
InputStickHID.removeStateListener(this);
|
|
super.onDestroy();
|
|
}
|
|
|
|
@Override
|
|
public void onStateChanged(int state) {
|
|
Log.d(_TAG, "state changed: "+state);
|
|
switch (state) {
|
|
case ConnectionManager.STATE_READY:
|
|
/*
|
|
Intent typeQueue = new Intent(this, InputStickService.class);
|
|
typeQueue.setAction(TYPE_QUEUE);
|
|
startService(typeQueue);
|
|
*/
|
|
new AsyncTask<Object, Object, Object>() {
|
|
|
|
@Override
|
|
protected Object doInBackground(Object... params) {
|
|
try {
|
|
Thread.sleep(1000, 0);
|
|
} catch (InterruptedException e) {
|
|
e.printStackTrace();
|
|
}
|
|
typeQueue();
|
|
return null;
|
|
}
|
|
|
|
};
|
|
typeQueue();
|
|
break;
|
|
case ConnectionManager.STATE_DISCONNECTED:
|
|
Log.d(_TAG, "stopping service. State = "+state);
|
|
stopSelf();
|
|
break;
|
|
case ConnectionManager.STATE_FAILURE:
|
|
Log.d(_TAG, "stopping service. State = "+state);
|
|
stopSelf();
|
|
AlertDialog ad = InputStickHID.getDownloadDialog(this);
|
|
if (ad != null) {
|
|
//Utility application not installed
|
|
ad.show();
|
|
} else {
|
|
Toast.makeText(this, "Failure connecting to InputStick!", Toast.LENGTH_LONG).show();
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
}
|