/** * Create an Action object * * @param context Android context * @param messageTypeToListenTo the type of message that concern this action * @param poll the poll to fill in this action * @param timeOut the maximum time in millisecond that this action can last */ public AbstractAction( Context context, String messageTypeToListenTo, ProtocolPoll poll, long timeOut) { TAG = this.getClass().getSimpleName(); // Map of message received this.messagesReceived = new HashMap<String, ProtocolMessageContainer>(); // Store some important entities that will be used in the actions this.context = context; this.poll = poll; this.timeOut = timeOut; for (Participant p : poll.getParticipants().values()) { if (p.getUniqueId() .equals(AndroidApplication.getInstance().getNetworkInterface().getMyUniqueId())) { this.me = (ProtocolParticipant) p; } } if (messageTypeToListenTo != null) { // Subscribing to the messageArrived events to update immediately LocalBroadcastManager.getInstance(context) .registerReceiver(this.voteMessageReceiver, new IntentFilter(messageTypeToListenTo)); } }
/** * Indicate if conditions to go to next step are fulfilled * * @return true if conditions are fulfilled, false otherwise */ protected boolean readyToGoToNextState() { Collection<Participant> activeParticipants = new ArrayList<Participant>(); for (Participant p : poll.getParticipants().values()) { activeParticipants.add(p); } activeParticipants.removeAll(poll.getExcludedParticipants().values()); activeParticipants.removeAll(poll.getCompletelyExcludedParticipants().values()); for (Participant p : activeParticipants) { if (!this.messagesReceived.containsKey(p.getUniqueId())) { Log.w( TAG, "Message from " + p.getUniqueId() + " (" + p.getIdentification() + ") not received"); return false; } } return true; }
@Override public void onReceive(Context context, Intent intent) { String action = intent.getStringExtra("action"); if (action == null || action.equals("")) { return; } else if (action.equals("left")) { Participant p = poll.getParticipants().get(intent.getStringExtra("id")); if (p != null) { if (AbstractAction.this instanceof SetupRoundAction) { poll.getCompletelyExcludedParticipants().put(p.getUniqueId(), p); // notify exclusion LocalBroadcastManager.getInstance(AndroidApplication.getInstance()) .sendBroadcast( new Intent(BroadcastIntentTypes.proofVerificationFailed) .putExtra("type", 2) .putExtra("participant", p.getIdentification())); Log.w( TAG, "Participant " + p.getIdentification() + " (" + p.getUniqueId() + ") went out of the network before submitting the setup value, so he was completely excluded (also from recovery)."); } else { poll.getExcludedParticipants().put(p.getUniqueId(), p); // notify exclusion LocalBroadcastManager.getInstance(AndroidApplication.getInstance()) .sendBroadcast( new Intent(BroadcastIntentTypes.proofVerificationFailed) .putExtra("type", 3) .putExtra("participant", p.getIdentification())); Log.w( TAG, "Participant " + p.getIdentification() + " (" + p.getUniqueId() + ") was added to excluded list since he went out of the network."); } } } if (readyToGoToNextState() && !actionTerminated) { goToNextState(); } }
@Override public void run() { if (actionTerminated) return; stopTimer(); if (numberOfProcessedMessages < numberMessagesReceived) { startTimer(10000); Log.d( TAG, "Timer timed out by not all messages were processed. So restarting time out timer"); return; } for (Participant p : poll.getParticipants().values()) { if (AbstractAction.this instanceof SetupRoundAction) { if (!messagesReceived.containsKey(p.getUniqueId())) { // notify exclusion LocalBroadcastManager.getInstance(AndroidApplication.getInstance()) .sendBroadcast( new Intent(BroadcastIntentTypes.proofVerificationFailed) .putExtra("type", 2) .putExtra("participant", p.getIdentification())); poll.getCompletelyExcludedParticipants().put(p.getUniqueId(), p); } Log.w( TAG, "Participant " + p.getIdentification() + " (" + p.getUniqueId() + ") did not responde before timed out for submitting the setup value, so he was completely excluded (also from recovery)."); } else if (!messagesReceived.containsKey(p.getUniqueId()) && !poll.getCompletelyExcludedParticipants().containsKey(p.getUniqueId())) { poll.getExcludedParticipants().put(p.getUniqueId(), p); // notify exclusion LocalBroadcastManager.getInstance(AndroidApplication.getInstance()) .sendBroadcast( new Intent(BroadcastIntentTypes.proofVerificationFailed) .putExtra("type", 2) .putExtra("participant", p.getIdentification())); Log.w( TAG, "Excluding participant " + p.getIdentification() + " (" + p.getUniqueId() + ") because not sending his message."); } } goToNextState(); }