2014-06-01 01:06:58 -04:00
|
|
|
package com.inputstick.api.basic;
|
|
|
|
|
2014-09-29 15:29:52 -04:00
|
|
|
import java.util.Timer;
|
|
|
|
import java.util.TimerTask;
|
2014-06-01 01:06:58 -04:00
|
|
|
import java.util.Vector;
|
|
|
|
|
2014-09-29 15:29:52 -04:00
|
|
|
import android.app.AlertDialog;
|
2014-06-01 01:06:58 -04:00
|
|
|
import android.app.Application;
|
2014-09-29 15:29:52 -04:00
|
|
|
import android.content.Context;
|
|
|
|
import android.content.DialogInterface;
|
|
|
|
import android.content.Intent;
|
|
|
|
import android.net.Uri;
|
2014-06-01 01:06:58 -04:00
|
|
|
|
|
|
|
import com.inputstick.api.BTConnectionManager;
|
|
|
|
import com.inputstick.api.ConnectionManager;
|
|
|
|
import com.inputstick.api.HIDInfo;
|
|
|
|
import com.inputstick.api.IPCConnectionManager;
|
|
|
|
import com.inputstick.api.InputStickDataListener;
|
2014-09-29 15:29:52 -04:00
|
|
|
import com.inputstick.api.InputStickError;
|
2014-06-01 01:06:58 -04:00
|
|
|
import com.inputstick.api.InputStickStateListener;
|
2014-09-29 15:29:52 -04:00
|
|
|
import com.inputstick.api.OnEmptyBufferListener;
|
2014-06-01 01:06:58 -04:00
|
|
|
import com.inputstick.api.Packet;
|
2014-09-29 15:29:52 -04:00
|
|
|
import com.inputstick.api.Util;
|
2014-06-01 01:06:58 -04:00
|
|
|
import com.inputstick.api.hid.HIDTransaction;
|
|
|
|
import com.inputstick.api.hid.HIDTransactionQueue;
|
|
|
|
import com.inputstick.init.InitManager;
|
|
|
|
|
|
|
|
public class InputStickHID implements InputStickStateListener, InputStickDataListener {
|
|
|
|
|
2014-09-29 15:29:52 -04:00
|
|
|
public static final int INTERFACE_KEYBOARD = 0;
|
|
|
|
public static final int INTERFACE_CONSUMER = 1;
|
|
|
|
public static final int INTERFACE_MOUSE = 2;
|
|
|
|
|
2014-06-01 01:06:58 -04:00
|
|
|
|
2014-09-29 15:29:52 -04:00
|
|
|
//private static final String mTag = "InputStickBasic";
|
2014-06-01 01:06:58 -04:00
|
|
|
private static ConnectionManager mConnectionManager;
|
|
|
|
|
|
|
|
private static Vector<InputStickStateListener> mStateListeners = new Vector<InputStickStateListener>();
|
|
|
|
|
2014-09-29 15:29:52 -04:00
|
|
|
|
2014-06-01 01:06:58 -04:00
|
|
|
private static InputStickHID instance = new InputStickHID();
|
2014-09-29 15:29:52 -04:00
|
|
|
private static HIDInfo mHIDInfo;
|
2014-06-01 01:06:58 -04:00
|
|
|
|
|
|
|
private static HIDTransactionQueue keyboardQueue;
|
|
|
|
private static HIDTransactionQueue mouseQueue;
|
|
|
|
private static HIDTransactionQueue consumerQueue;
|
|
|
|
|
2014-09-29 15:29:52 -04:00
|
|
|
// >= FW 0.93
|
|
|
|
private static Timer t1;
|
|
|
|
private static boolean constantUpdateMode;
|
|
|
|
|
2014-06-01 01:06:58 -04:00
|
|
|
private InputStickHID() {
|
|
|
|
}
|
|
|
|
|
|
|
|
public static InputStickHID getInstance() {
|
|
|
|
return instance;
|
|
|
|
}
|
|
|
|
|
|
|
|
private static void init() {
|
2014-09-29 15:29:52 -04:00
|
|
|
mHIDInfo = new HIDInfo();
|
|
|
|
constantUpdateMode = false;
|
|
|
|
keyboardQueue = new HIDTransactionQueue(INTERFACE_KEYBOARD, mConnectionManager);
|
|
|
|
mouseQueue = new HIDTransactionQueue(INTERFACE_MOUSE, mConnectionManager);
|
|
|
|
consumerQueue = new HIDTransactionQueue(INTERFACE_CONSUMER, mConnectionManager);
|
2014-06-01 01:06:58 -04:00
|
|
|
|
|
|
|
mConnectionManager.addStateListener(instance);
|
|
|
|
mConnectionManager.addDataListener(instance);
|
|
|
|
mConnectionManager.connect();
|
|
|
|
}
|
|
|
|
|
|
|
|
//direct Bluetooth connection, custom InitManager
|
|
|
|
public static void connect(Application app, String mac, byte[] key, InitManager initManager) {
|
|
|
|
mConnectionManager = new BTConnectionManager(initManager, app, mac, key);
|
|
|
|
init();
|
|
|
|
}
|
|
|
|
|
|
|
|
//direct Bluetooth connection
|
|
|
|
public static void connect(Application app, String mac, byte[] key) {
|
|
|
|
mConnectionManager = new BTConnectionManager(new InitManager(key), app, mac, key);
|
|
|
|
init();
|
|
|
|
}
|
|
|
|
|
|
|
|
//use background service & DeviceManager
|
|
|
|
public static void connect(Application app) {
|
|
|
|
mConnectionManager = new IPCConnectionManager(app);
|
|
|
|
init();
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void disconnect() {
|
|
|
|
//TODO check state?
|
|
|
|
mConnectionManager.disconnect();
|
|
|
|
}
|
|
|
|
|
|
|
|
public static int getState() {
|
|
|
|
if (mConnectionManager != null) {
|
|
|
|
return mConnectionManager.getState();
|
|
|
|
} else {
|
|
|
|
return ConnectionManager.STATE_DISCONNECTED;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-29 15:29:52 -04:00
|
|
|
public static int getErrorCode() {
|
|
|
|
if (mConnectionManager != null) {
|
|
|
|
return mConnectionManager.getErrorCode();
|
|
|
|
} else {
|
|
|
|
return InputStickError.ERROR_UNKNOWN;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-06-01 01:06:58 -04:00
|
|
|
public static boolean isReady() {
|
|
|
|
if (getState() == ConnectionManager.STATE_READY) {
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void addStateListener(InputStickStateListener listener) {
|
|
|
|
if (listener != null) {
|
2014-09-29 15:29:52 -04:00
|
|
|
if ( !mStateListeners.contains(listener)) {
|
|
|
|
mStateListeners.add(listener);
|
|
|
|
}
|
2014-06-01 01:06:58 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void removeStateListener(InputStickStateListener listener) {
|
|
|
|
if (listener != null) {
|
|
|
|
mStateListeners.remove(listener);
|
|
|
|
}
|
|
|
|
}
|
2014-09-29 15:29:52 -04:00
|
|
|
|
|
|
|
public static void addBufferEmptyListener(OnEmptyBufferListener listener) {
|
|
|
|
if (listener != null) {
|
|
|
|
keyboardQueue.addBufferEmptyListener(listener);
|
|
|
|
mouseQueue.addBufferEmptyListener(listener);
|
|
|
|
consumerQueue.addBufferEmptyListener(listener);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void removeBufferEmptyListener(OnEmptyBufferListener listener) {
|
|
|
|
if (listener != null) {
|
|
|
|
keyboardQueue.removeBufferEmptyListener(listener);
|
|
|
|
mouseQueue.removeBufferEmptyListener(listener);
|
|
|
|
consumerQueue.removeBufferEmptyListener(listener);
|
|
|
|
}
|
|
|
|
}
|
2014-06-01 01:06:58 -04:00
|
|
|
|
|
|
|
public static void addKeyboardTransaction(HIDTransaction transaction) {
|
|
|
|
keyboardQueue.addTransaction(transaction);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void addMouseTransaction(HIDTransaction transaction) {
|
|
|
|
mouseQueue.addTransaction(transaction);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void addConsumerTransaction(HIDTransaction transaction) {
|
|
|
|
consumerQueue.addTransaction(transaction);
|
|
|
|
}
|
|
|
|
|
2014-09-29 15:29:52 -04:00
|
|
|
public static void clearKeyboardBuffer() {
|
|
|
|
keyboardQueue.clearBuffer();
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void clearMouseBuffer() {
|
|
|
|
mouseQueue.clearBuffer();
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void clearConsumerBuffer() {
|
|
|
|
consumerQueue.clearBuffer();
|
|
|
|
}
|
|
|
|
|
2014-06-01 01:06:58 -04:00
|
|
|
public static boolean sendPacket(Packet p) {
|
|
|
|
if (mConnectionManager != null) {
|
|
|
|
mConnectionManager.sendPacket(p);
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2014-09-29 15:29:52 -04:00
|
|
|
public void onStateChanged(int state) {
|
|
|
|
if ((state == ConnectionManager.STATE_DISCONNECTED) && (t1 != null)) {
|
|
|
|
t1.cancel();
|
|
|
|
t1 = null;
|
|
|
|
}
|
2014-06-01 01:06:58 -04:00
|
|
|
for (InputStickStateListener listener : mStateListeners) {
|
|
|
|
listener.onStateChanged(state);
|
|
|
|
}
|
|
|
|
}
|
2014-09-29 15:29:52 -04:00
|
|
|
|
|
|
|
public static boolean isKeyboardLocalBufferEmpty() {
|
|
|
|
return keyboardQueue.isLocalBufferEmpty();
|
|
|
|
}
|
|
|
|
public static boolean isMouseLocalBufferEmpty() {
|
|
|
|
return mouseQueue.isLocalBufferEmpty();
|
|
|
|
}
|
|
|
|
public static boolean isConsumerLocalBufferEmpty() {
|
|
|
|
return consumerQueue.isLocalBufferEmpty();
|
|
|
|
}
|
|
|
|
|
|
|
|
public static boolean isKeyboardRemoteBufferEmpty() {
|
|
|
|
return keyboardQueue.isRemoteBufferEmpty();
|
|
|
|
}
|
|
|
|
public static boolean isMouseRemoteBufferEmpty() {
|
|
|
|
return mouseQueue.isRemoteBufferEmpty();
|
|
|
|
}
|
|
|
|
public static boolean isConsumerRemoteBufferEmpty() {
|
|
|
|
return consumerQueue.isRemoteBufferEmpty();
|
|
|
|
}
|
2014-06-01 01:06:58 -04:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onInputStickData(byte[] data) {
|
|
|
|
if (data[0] == Packet.CMD_HID_STATUS) {
|
|
|
|
mHIDInfo.update(data);
|
2014-09-29 15:29:52 -04:00
|
|
|
|
|
|
|
if (mHIDInfo.isSentToHostInfoAvailable()) {
|
|
|
|
// >= FW 0.93
|
|
|
|
keyboardQueue.deviceReady(mHIDInfo, mHIDInfo.getKeyboardReportsSentToHost());
|
|
|
|
mouseQueue.deviceReady(mHIDInfo, mHIDInfo.getMouseReportsSentToHost());
|
|
|
|
consumerQueue.deviceReady(mHIDInfo, mHIDInfo.getConsumerReportsSentToHost());
|
|
|
|
|
|
|
|
if ( !constantUpdateMode) {
|
|
|
|
Util.log("Constatnt update mode enabled");
|
|
|
|
constantUpdateMode = true;
|
|
|
|
t1 = new Timer();
|
|
|
|
t1.schedule(new TimerTask() {
|
|
|
|
@Override
|
|
|
|
public void run() {
|
|
|
|
keyboardQueue.sendToBuffer(false);
|
|
|
|
mouseQueue.sendToBuffer(false);
|
|
|
|
consumerQueue.sendToBuffer(false);
|
|
|
|
}
|
|
|
|
}, 5,5);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
//previous FW versions
|
|
|
|
if (mHIDInfo.isKeyboardReady()) {
|
|
|
|
keyboardQueue.deviceReady(null, 0);
|
|
|
|
}
|
|
|
|
if (mHIDInfo.isMouseReady()) {
|
|
|
|
mouseQueue.deviceReady(null, 0);
|
|
|
|
}
|
|
|
|
if (mHIDInfo.isConsumerReady()) {
|
|
|
|
consumerQueue.deviceReady(null, 0);
|
|
|
|
}
|
2014-06-01 01:06:58 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
InputStickKeyboard.setLEDs(mHIDInfo.getNumLock(), mHIDInfo.getCapsLock(), mHIDInfo.getScrollLock());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-09-29 15:29:52 -04:00
|
|
|
public static AlertDialog getDownloadDialog(final Context ctx) {
|
|
|
|
if (mConnectionManager.getErrorCode() == InputStickError.ERROR_ANDROID_NO_UTILITY_APP) {
|
|
|
|
AlertDialog.Builder downloadDialog = new AlertDialog.Builder(ctx);
|
|
|
|
downloadDialog.setTitle("No InputStickUtility app installed");
|
|
|
|
downloadDialog.setMessage("InputStickUtility is required to run this application. Download now?");
|
|
|
|
downloadDialog.setPositiveButton("Yes",
|
|
|
|
new DialogInterface.OnClickListener() {
|
|
|
|
@Override
|
|
|
|
public void onClick(DialogInterface dialogInterface, int i) {
|
|
|
|
final String appPackageName = "com.inputstick.apps.inputstickutility";
|
|
|
|
try {
|
|
|
|
ctx.startActivity(new Intent(
|
|
|
|
Intent.ACTION_VIEW, Uri
|
|
|
|
.parse("market://details?id="
|
|
|
|
+ appPackageName)));
|
|
|
|
} catch (android.content.ActivityNotFoundException anfe) {
|
|
|
|
ctx.startActivity(new Intent(
|
|
|
|
Intent.ACTION_VIEW,
|
|
|
|
Uri.parse("http://play.google.com/store/apps/details?id="
|
|
|
|
+ appPackageName)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
downloadDialog.setNegativeButton("No",
|
|
|
|
new DialogInterface.OnClickListener() {
|
|
|
|
@Override
|
|
|
|
public void onClick(DialogInterface dialogInterface, int i) {
|
|
|
|
}
|
|
|
|
});
|
|
|
|
return downloadDialog.show();
|
|
|
|
} else {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-01 01:06:58 -04:00
|
|
|
|
|
|
|
}
|