package com.kuxhausen.huemore.net.dev;
import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import java.lang.ref.WeakReference;
/**
* Base implementation of a service that represents a device driver in bound Inter-Process
* Communication with the device manager
*/
public abstract class IpcMinion extends Service implements DeviceListener {
/**
* When bound to the DeviceManager, keep track of the DeviceManager's messenger
*/
Messenger mDeviceManagerMessenger;
int mBrightness = 0;
/**
* Target we publish for the DeviceManager to send messages to our IncomingHandler.
*/
final Messenger mMessenger = new Messenger(new IncomingHandler(new WeakReference<>(this)));
public abstract DeviceDriver getDeviceDriver();
@Override
public void onCreate() {
super.onCreate();
DevLogger.debugLog("SimpleDevice: onCreate");
}
@Override
public void onDestroy() {
super.onDestroy();
DevLogger.debugLog("SimpleDevice: onDestroy");
}
/**
* When binding to this service, return an interface to our messenger for sending us messages
*/
@Override
public IBinder onBind(Intent intent) {
return mMessenger.getBinder();
}
@Override
public void deviceStateChanged(StateMessage state) {
if (mDeviceManagerMessenger != null) {
try {
mDeviceManagerMessenger.send(
Message.obtain(null, IpcMaster.MSG_OBSERVED_STATEMESSAGE, state));
} catch (RemoteException e) {
// The client is dead. Remove references to it;
mDeviceManagerMessenger = null;
}
}
}
/**
* Handles incoming messages from DeviceManager
*/
private static class IncomingHandler extends Handler {
WeakReference<IpcMinion> mManagerWeakReference;
public IncomingHandler(WeakReference<IpcMinion> managerWeakReference) {
mManagerWeakReference = managerWeakReference;
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case IpcMaster.MSG_REGISTER_MANAGER:
DevLogger.debugLog("SimpleDeviceRecieved: registerClient");
if (mManagerWeakReference.get().mDeviceManagerMessenger != null) {
// Something bad has happened, clear out any state from the old connection
}
mManagerWeakReference.get().mDeviceManagerMessenger = msg.replyTo;
try {
mManagerWeakReference.get().mDeviceManagerMessenger.send(
Message.obtain(null, IpcMaster.MSG_DRIVER_PID,
android.os.Process.myPid(), 0));
} catch (RemoteException e) {
// The client is dead. Remove references to it;
mManagerWeakReference.get().mDeviceManagerMessenger = null;
}
if (DevLogger.NET_DEBUG) {
// When debugging, generate some test messages
new NetExerciser().execute(msg.replyTo, mManagerWeakReference.get().mMessenger);
}
break;
case IpcMaster.MSG_UNREGISTER_MANAGER:
DevLogger.debugLog("SimpleDeviceRecieved: unregisterClient");
mManagerWeakReference.get().mDeviceManagerMessenger = null;
break;
case IpcMaster.MSG_TARGET_STATEMESSAGE:
mManagerWeakReference.get().getDeviceDriver().targetStateChanged((StateMessage) msg.obj);
break;
case IpcMaster.MSG_TARGET_BULBNAME:
mManagerWeakReference.get().getDeviceDriver().bulbNameChanged((BulbNameMessage) msg.obj);
break;
case IpcMaster.MSG_LAUNCH_CONFIGURATION:
mManagerWeakReference.get().getDeviceDriver().launchOnboarding();
break;
case IpcMaster.MSG_CONNECTIONS_CONNECTIVITY:
try {
ConnectivityMessage message =
mManagerWeakReference.get().getDeviceDriver().getConnectionConnectivity();
mManagerWeakReference.get().mDeviceManagerMessenger.send(Message.
obtain(null, IpcMaster.MSG_CONNECTIONS_CONNECTIVITY, message));
} catch (RemoteException e) {
// The client is dead. Remove references to it;
mManagerWeakReference.get().mDeviceManagerMessenger = null;
}
break;
case IpcMaster.MSG_BULBS_CONNECTIVITY:
try {
ConnectivityMessage message =
mManagerWeakReference.get().getDeviceDriver().getBulbConnectivity();
mManagerWeakReference.get().mDeviceManagerMessenger.send(Message.
obtain(null, IpcMaster.MSG_BULBS_CONNECTIVITY, message));
} catch (RemoteException e) {
// The client is dead. Remove references to it;
mManagerWeakReference.get().mDeviceManagerMessenger = null;
}
break;
case IpcMaster.MSG_DEBUG_PING:
DevLogger.debugLog("SimpleDeviceService.PING " + msg.arg1);
DevLogger.getLogger().accumulate("SDS.PING", msg.arg1);
mManagerWeakReference.get().mBrightness = msg.arg1;
if (DevLogger.NET_DEBUG) {
NetExerciser.simulateCrash(.05);
NetExerciser.simulateWork(5000);
}
try {
mManagerWeakReference.get().mDeviceManagerMessenger.send(
Message.obtain(null, IpcMaster.MSG_DEBUG_ACK, msg.arg1, 0));
} catch (RemoteException e) {
// The client is dead. Remove references to it;
mManagerWeakReference.get().mDeviceManagerMessenger = null;
}
break;
case IpcMaster.MSG_DEBUG_ACK:
DevLogger.debugLog("SimpleDeviceService.ACK " + msg.arg1);
DevLogger.getLogger().accumulate("SDS.ACK", msg.arg1);
default:
super.handleMessage(msg);
}
}
}
}