package eu.musesproject.client.actuators; /* * #%L * musesclient * %% * Copyright (C) 2013 - 2014 HITEC * %% * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * #L% */ import android.content.Context; import android.content.Intent; import android.util.Log; import eu.musesproject.client.R; import eu.musesproject.client.contextmonitoring.UserContextMonitoringController; import eu.musesproject.client.contextmonitoring.service.aidl.DummyCommunication; import eu.musesproject.client.model.actuators.ResponseInfoAP; import eu.musesproject.client.model.decisiontable.Action; import eu.musesproject.client.model.decisiontable.Decision; import eu.musesproject.client.ui.DebugFileLog; import eu.musesproject.client.ui.DialogController; import eu.musesproject.client.ui.NotificationController; import eu.musesproject.server.risktrust.SolvingRiskTreatment; import java.util.LinkedList; import java.util.Queue; /** * Created by christophstanik on 4/15/14. * * Class to send feedback to MUSES UI * Feedback types: * - login successful * - login unsuccessful * - show feedback based on a {@link eu.musesproject.client.model.decisiontable.Decision} */ public class FeedbackActuator implements IFeedbackActuator { private static final String TAG = FeedbackActuator.class.getSimpleName(); private static final String APP_TAG = "APP_TAG"; private static IUICallback callback; private Context context; Queue<Decision> decisionQueue; public FeedbackActuator(Context context) { this.context = context; decisionQueue = new LinkedList<Decision>(); NotificationController.getInstance(context).create(decisionQueue.size()); } @Override public void showFeedback(Decision decision) { DebugFileLog.write(TAG + "| called: showFeedback(Decision decision)"); Log.d(TAG, "called: showFeedback(Decision decision)"); if(decision != null && decision.getName() != null) { try { // check if the decision is already in the queue for the feedback dialogs, // in order to avoid duplicate entries for (Decision bufferedDecision: decisionQueue) { if(bufferedDecision.getRiskCommunication().getRiskTreatment()[0].getTextualDescription().equals( decision.getRiskCommunication().getRiskTreatment()[0].getTextualDescription())) { Log.d(TAG, "duplicate found"); DebugFileLog.write(TAG + "| duplicate found"); return; // do not add a duplicate feedback } } } catch (Exception e) { e.printStackTrace(); } decisionQueue.add(decision); Log.d(TAG, "new feedback dialog request; queue size:" + decisionQueue.size() + " " + decision.getRiskCommunication().getRiskTreatment()[0].getTextualDescription()); DebugFileLog.write(TAG + "| new feedback dialog request; queue size:" + decisionQueue.size() + " " + decision.getRiskCommunication().getRiskTreatment()[0].getTextualDescription()); // just show a new dialog if there is no other currently displayed if (decisionQueue.size() == 1) { createFeedbackDialog(decision); } // update the notification bar to visualize if there are dialogs/messages or not NotificationController.getInstance(context).create(decisionQueue.size()); } } private void showNextFeedback(Decision decision) { DebugFileLog.write(TAG + "| showNextFeedback " + decision.getRiskCommunication().getRiskTreatment()[0].getTextualDescription()); Log.d(TAG, "showNextFeedback " + decision.getRiskCommunication().getRiskTreatment()[0].getTextualDescription()); createFeedbackDialog(decision); } private void createFeedbackDialog(Decision decision) { Log.d(TAG, "Info U, Actuator -> FeedbackActuator showing feedback with decision: " + decision.getName()); DebugFileLog.write(TAG + "| Info U, Actuator -> FeedbackActuator showing feedback with decision: " + decision.getName()); String decisionId = decision.getDecision_id(); String dialogBody = decision.getRiskCommunication().getRiskTreatment()[0].getTextualDescription(); String dialogTitle = ""; boolean hasOpportunity = decision.getSolving_risktreatment() == SolvingRiskTreatment.OPPORTUNITY; Intent dialogIntent = new Intent(context, DialogController.class); dialogIntent.putExtra(DialogController.KEY_DECISION_ID, decisionId); dialogIntent.putExtra(DialogController.KEY_DIALOG_BODY, dialogBody); dialogIntent.putExtra(DialogController.KEY_DIALOG_HAS_OPPORTUNITY, hasOpportunity); dialogIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NEW_TASK); if(decision.getName().equalsIgnoreCase(Decision.GRANTED_ACCESS)){ // remove it from the queue, because it does not provide a dialog in which the user can click // on a button removeFeedbackFromQueue(); // send user behavior to the server. // since, GRANTED is a situation where the user has no visible pop up, we will send an // automatic generated behavior, which is GRANTED Action action = new Action(Decision.GRANTED_ACCESS, System.currentTimeMillis()); if(context != null) { UserContextMonitoringController.getInstance(context).sendUserBehavior(action, decisionId); } return; } else if(decision.getName().equalsIgnoreCase(Decision.MAYBE_ACCESS_WITH_RISKTREATMENTS)) { dialogTitle = context.getString(R.string.feedback_dialog_title_maybe); dialogIntent.putExtra(DialogController.KEY_DIALOG_TITLE, dialogTitle); dialogIntent.putExtra(DialogController.KEY_DIALOG, DialogController.MAYBE); } else if(decision.getName().equalsIgnoreCase(Decision.UPTOYOU_ACCESS_WITH_RISKCOMMUNICATION)) { dialogTitle = context.getString(R.string.feedback_dialog_title_uptouser); dialogIntent.putExtra(DialogController.KEY_DIALOG_TITLE, dialogTitle); dialogIntent.putExtra(DialogController.KEY_DIALOG, DialogController.UP_TO_USER); } else if(decision.getName().equalsIgnoreCase(Decision.STRONG_DENY_ACCESS) || decision.getName().equalsIgnoreCase(Decision.DEFAULT_DENY_ACCESS)) { dialogTitle = context.getString(R.string.feedback_dialog_title_deny); dialogIntent.putExtra(DialogController.KEY_DIALOG_TITLE, dialogTitle); dialogIntent.putExtra(DialogController.KEY_DIALOG, DialogController.DENY); } context.startActivity(dialogIntent); } @Override public void sendFeedbackToMUSESAwareApp(Decision decision, Context context) { try { eu.musesproject.server.risktrust.RiskTreatment riskTreatment[] = decision.getRiskCommunication().getRiskTreatment(); ResponseInfoAP infoAP; if(decision.getName().equals(Decision.STRONG_DENY_ACCESS) || decision.getName().equals(Decision.DEFAULT_DENY_ACCESS) ) { infoAP = ResponseInfoAP.DENY; } else { infoAP = ResponseInfoAP.ACCEPT; } new DummyCommunication(context).sendResponse(infoAP, riskTreatment[0]); } catch (Exception e) { e.printStackTrace(); // no risk treatment } } @Override public void removeFeedbackFromQueue() { DebugFileLog.write(TAG + "| removeFeedbackFromQueue"); Log.d(TAG, "1. remove feedback from queue"); // removes the last feedback dialog if(decisionQueue != null) { try { decisionQueue.remove(); } catch (Exception e) { Log.d(TAG, "1.1 no more entries in the queue"); DebugFileLog.write(TAG + "| no more entries in the queue"); } if(!decisionQueue.isEmpty()) { // triggers to show the next feedback dialog if there is any Log.d(TAG, "2. Decision queue size is (after removal): " + decisionQueue.size()); DebugFileLog.write(TAG + "| Decision queue size is (after removal): " + decisionQueue.size()); showNextFeedback(decisionQueue.element()); } // update the notification bar to visualize if there are dialogs/messages or not NotificationController.getInstance(context).create(decisionQueue.size()); } } @Override public void showCurrentTopFeedback() { if(decisionQueue != null && decisionQueue.size() > 0) { DebugFileLog.write(TAG + "| showCurrentTopFeedback"); createFeedbackDialog(decisionQueue.peek()); } } public void sendLoginResponseToUI(boolean result, String msg, int detailedStatus) { Log.d(APP_TAG, "Info U, Actuator -> FeedbackActuator sending login response with result: " + result); Log.d(TAG, "called: sendLoginResponseToUI(boolean result)"); if(callback!=null) { callback.onLogin(result, msg, detailedStatus); } } public void registerCallback(IUICallback iUICallback) { callback = iUICallback; } public void unregisterCallback(IUICallback iUICallback) { callback = iUICallback; } }