181 lines
5.3 KiB
Java
181 lines
5.3 KiB
Java
package com.inputstick.api;
|
|
|
|
import java.lang.ref.WeakReference;
|
|
|
|
import android.app.Application;
|
|
import android.content.ComponentName;
|
|
import android.content.Context;
|
|
import android.content.Intent;
|
|
import android.content.ServiceConnection;
|
|
import android.content.pm.PackageManager;
|
|
import android.content.pm.PackageManager.NameNotFoundException;
|
|
import android.os.Bundle;
|
|
import android.os.Handler;
|
|
import android.os.IBinder;
|
|
import android.os.Message;
|
|
import android.os.Messenger;
|
|
|
|
public class IPCConnectionManager extends ConnectionManager {
|
|
|
|
//private static final String mTag = "IPCConnectionManager";
|
|
|
|
public static final int SERVICE_CMD_CONNECT = 1;
|
|
public static final int SERVICE_CMD_DISCONNECT = 2;
|
|
public static final int SERVICE_CMD_DATA = 3;
|
|
public static final int SERVICE_CMD_STATE = 4;
|
|
|
|
Context mCtx;
|
|
Messenger mService = null;
|
|
boolean mBound;
|
|
boolean initSent;
|
|
final Messenger mMessenger = new Messenger(new IncomingHandler(this));
|
|
|
|
private static class IncomingHandler extends Handler {
|
|
private final WeakReference<IPCConnectionManager> ref;
|
|
|
|
IncomingHandler(IPCConnectionManager manager) {
|
|
ref = new WeakReference<IPCConnectionManager>(manager);
|
|
}
|
|
|
|
@Override
|
|
public void handleMessage(Message msg) {
|
|
if (ref == null) return;
|
|
IPCConnectionManager manager = ref.get();
|
|
if (manager != null) {
|
|
switch (msg.what) {
|
|
case SERVICE_CMD_DATA:
|
|
byte[] data = null;
|
|
Bundle b = msg.getData();
|
|
if (b != null) {
|
|
data = b.getByteArray("data");
|
|
manager.onData(data);
|
|
}
|
|
break;
|
|
case SERVICE_CMD_STATE:
|
|
manager.stateNotify(msg.arg1);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private ServiceConnection mConnection = new ServiceConnection() {
|
|
public void onServiceConnected(ComponentName className, IBinder service) {
|
|
mService = new Messenger(service);
|
|
mBound = true;
|
|
sendConnectMessage();
|
|
}
|
|
|
|
public void onServiceDisconnected(ComponentName className) {
|
|
// unexpectedly disconnected from service
|
|
mService = null;
|
|
mBound = false;
|
|
mErrorCode = InputStickError.ERROR_ANDROID_SERVICE_DISCONNECTED;
|
|
stateNotify(STATE_FAILURE);
|
|
stateNotify(STATE_DISCONNECTED);
|
|
}
|
|
};
|
|
//SERVICE=========================================================
|
|
|
|
|
|
|
|
|
|
|
|
private void sendConnectMessage() {
|
|
Bundle b = new Bundle();
|
|
b.putLong("TIME", System.currentTimeMillis());
|
|
sendMessage(SERVICE_CMD_CONNECT, 0, 0, b);
|
|
}
|
|
|
|
|
|
private void sendMessage(int what, int arg1, int arg2, Bundle b) {
|
|
Message msg;
|
|
try {
|
|
msg = Message.obtain(null, what, arg1, 0, null);
|
|
msg.replyTo = mMessenger;
|
|
msg.setData(b);
|
|
mService.send(msg);
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
|
|
private void sendMessage(int what, int arg1, int arg2, byte[] data) {
|
|
Bundle b;
|
|
b = new Bundle();
|
|
b.putByteArray("data", data);
|
|
sendMessage(what, arg1, arg2, b);
|
|
}
|
|
|
|
private void sendMessage(int what, int arg1, int arg2) {
|
|
sendMessage(what, arg1, arg2, (Bundle)null);
|
|
}
|
|
|
|
@Override
|
|
protected void onData(byte[] data) {
|
|
super.onData(data);
|
|
}
|
|
|
|
|
|
public IPCConnectionManager(Application app) {
|
|
mCtx = app.getApplicationContext();
|
|
}
|
|
|
|
@Override
|
|
public void connect() {
|
|
PackageManager pm = mCtx.getPackageManager();
|
|
boolean exists = true;
|
|
try {
|
|
pm.getPackageInfo("com.inputstick.apps.inputstickutility", PackageManager.GET_META_DATA);
|
|
} catch (NameNotFoundException e) {
|
|
exists = false;
|
|
}
|
|
|
|
if (exists) {
|
|
mErrorCode = InputStickError.ERROR_NONE;
|
|
Intent intent = new Intent();
|
|
intent.setComponent(new ComponentName("com.inputstick.apps.inputstickutility","com.inputstick.apps.inputstickutility.service.InputStickService"));
|
|
intent.putExtra("TIME", System.currentTimeMillis());
|
|
mCtx.startService(intent);
|
|
mCtx.bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
|
|
if (mBound) {
|
|
//already bound
|
|
sendConnectMessage();
|
|
}
|
|
} else {
|
|
mErrorCode = InputStickError.ERROR_ANDROID_NO_UTILITY_APP;
|
|
stateNotify(STATE_FAILURE);
|
|
stateNotify(STATE_DISCONNECTED);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void disconnect() {
|
|
if (mBound) {
|
|
sendMessage(SERVICE_CMD_DISCONNECT, 0, 0);
|
|
Intent intent = new Intent();
|
|
intent.setComponent(new ComponentName("com.inputstick.apps.inputstickutility","com.inputstick.apps.inputstickutility.service.InputStickService"));
|
|
mCtx.unbindService(mConnection);
|
|
mCtx.stopService(intent);
|
|
mBound = false;
|
|
//service will pass notification message (disconnected)
|
|
} else {
|
|
//just set state, there is nothing else to do
|
|
stateNotify(STATE_DISCONNECTED);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void sendPacket(Packet p) {
|
|
if ((mState == ConnectionManager.STATE_READY) || (mState == ConnectionManager.STATE_CONNECTED)) {
|
|
if (p.getRespond()) {
|
|
sendMessage(IPCConnectionManager.SERVICE_CMD_DATA, 1, 0, p.getBytes());
|
|
} else {
|
|
sendMessage(IPCConnectionManager.SERVICE_CMD_DATA, 0, 0, p.getBytes());
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
}
|