package eu.hgross.blaubot.android.views; import android.content.Context; import android.graphics.drawable.Drawable; import android.os.Handler; import android.os.Looper; import android.util.AttributeSet; import android.view.View; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import java.util.ArrayList; import java.util.List; import java.util.Map.Entry; import java.util.Set; import eu.hgross.blaubot.admin.AbstractAdminMessage; import eu.hgross.blaubot.admin.CensusMessage; import eu.hgross.blaubot.android.R; import eu.hgross.blaubot.core.Blaubot; import eu.hgross.blaubot.core.IBlaubotConnection; import eu.hgross.blaubot.core.State; import eu.hgross.blaubot.core.acceptor.IBlaubotConnectionManagerListener; import eu.hgross.blaubot.core.statemachine.IBlaubotConnectionStateMachineListener; import eu.hgross.blaubot.core.statemachine.states.IBlaubotState; import eu.hgross.blaubot.messaging.IBlaubotAdminMessageListener; import eu.hgross.blaubot.ui.IBlaubotDebugView; /** * Android view to display informations about the StateMachine's state. * * Add this view to a blaubot instance like this: stateView.registerBlaubotInstance(blaubot); * * @author Henning Gross {@literal (mail.to@henning-gross.de)} * */ public class KingdomView extends LinearLayout implements IBlaubotDebugView { private Handler mUiHandler; private Blaubot mBlaubot; private Context mContext; public KingdomView(Context context, AttributeSet attrs) { super(context, attrs); initView(context); } public KingdomView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); initView(context); } private void initView(Context context) { this.mContext = context; mUiHandler = new Handler(Looper.getMainLooper()); } private final static String NO_CENSUS_MESSAGE_SO_FAR_TEXT = "Got no census message so far"; private void updateUI(final CensusMessage censusMessage) { mUiHandler.post(new Runnable() { @Override public void run() { final List<View> stateItems = new ArrayList<>(); if(censusMessage != null) { final Set<Entry<String, State>> entries = censusMessage.getDeviceStates().entrySet(); for(Entry<String, State> entry : entries) { final String uniqueDeviceId = entry.getKey(); final State state = entry.getValue(); View item = createKingdomViewListItem(mContext, state, uniqueDeviceId); stateItems.add(item); } } // Never got a message if(stateItems.isEmpty()) { TextView tv = new TextView(mContext); tv.setText(NO_CENSUS_MESSAGE_SO_FAR_TEXT); stateItems.add(tv); } removeAllViews(); for(View v : stateItems) { addView(v); } } }); } /** * Creates a kingdom view list item * * @param context the context * @param state the state of the device to visualize * @param uniqueDeviceId the unique device id * @return the constructed view */ public static View createKingdomViewListItem(Context context, State state, String uniqueDeviceId) { final Drawable icon = ViewUtils.getDrawableForBlaubotState(context, state); View item = inflate(context, R.layout.blaubot_kingdom_view_list_item, null); TextView uniqueDeviceIdTextView = (TextView) item.findViewById(R.id.uniqueDeviceIdLabel); TextView stateTextView = (TextView) item.findViewById(R.id.stateLabel); ImageView iconImageView = (ImageView) item.findViewById(R.id.stateIcon); iconImageView.setImageDrawable(icon); uniqueDeviceIdTextView.setText(uniqueDeviceId); stateTextView.setText(state.toString()); return item; } private IBlaubotConnectionManagerListener mConnectionManagerListener = new IBlaubotConnectionManagerListener() { @Override public void onConnectionClosed(IBlaubotConnection connection) { } @Override public void onConnectionEstablished(IBlaubotConnection connection) { } }; private IBlaubotConnectionStateMachineListener mBlaubotConnectionStateMachineListener = new IBlaubotConnectionStateMachineListener() { @Override public void onStateChanged(IBlaubotState oldState, final IBlaubotState state) { if(State.getStateByStatemachineClass(state.getClass()) == State.Free) { updateUI(null); } } @Override public void onStateMachineStopped() { updateUI(null); } @Override public void onStateMachineStarted() { } }; private IBlaubotAdminMessageListener connectionLayerAdminMessageListener = new IBlaubotAdminMessageListener() { @Override public void onAdminMessage(AbstractAdminMessage adminMessage) { if(adminMessage instanceof CensusMessage) { updateUI((CensusMessage) adminMessage); } } }; /** * Register this view with the given blaubot instance * * @param blaubot * the blaubot instance to connect with */ @Override public void registerBlaubotInstance(Blaubot blaubot) { if (mBlaubot != null) { unregisterBlaubotInstance(); } this.mBlaubot = blaubot; this.mBlaubot.getConnectionStateMachine().addConnectionStateMachineListener(mBlaubotConnectionStateMachineListener); this.mBlaubot.getChannelManager().addAdminMessageListener(connectionLayerAdminMessageListener); this.mBlaubot.getConnectionManager().addConnectionListener(mConnectionManagerListener); // update updateUI(null); } @Override public void unregisterBlaubotInstance() { if(mBlaubot != null) { this.mBlaubot.getConnectionStateMachine().removeConnectionStateMachineListener(mBlaubotConnectionStateMachineListener); this.mBlaubot.getChannelManager().removeAdminMessageListener(connectionLayerAdminMessageListener); this.mBlaubot.getConnectionManager().removeConnectionListener(mConnectionManagerListener); } // force some updates updateUI(null); } }