/**
* DATP - Dismiss Alarm Tasker Plugin
* Copyright (C) 2014
*
* DATP is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DATP is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @author Fero
*/
package fero.taskerplugin.dismissalarm;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Toast;
import fero.taskerplugin.dismissalarm.event.ui.ConfigurationDismissedAlarmActivity;
import fero.taskerplugin.dismissalarm.utilities.BundleScrubber;
import fero.xposed.dismissalarm.Constants;
import fero.xposed.dismissalarm.Logger;
import fero.xposed.dismissalarm.R;
/**
* This is the receiver for the dismiss alarm intent provided by the Xposed
* setDismissState hook method and for the Takser event plugin. Upon receipt of
* the Xposed dismiss alarm intent the alarm label will be stored and used to
* respond to the Tasker QUERY_EVENT by checking the configuration alarm against
* the dismissed one.
*
* NOTE: Tasker event protocol was added in v4.3b5 and may require download and
* installation from Tasker's beta page:
*
* http://tasker.dinglisch.net/beta.html
*/
public class DismissAlarmReceiver extends BroadcastReceiver {
/**
* Intent to ask Takser to re-query this plug-in event
*/
private static final Intent INTENT_REQUEST_REQUERY = new Intent(com.twofortyfouram.locale.Intent.ACTION_REQUEST_QUERY).putExtra(com.twofortyfouram.locale.Intent.EXTRA_ACTIVITY, ConfigurationDismissedAlarmActivity.class.getName());
/**
* Dismissed alarm label
*/
private static String _dismissedAlarmLabel = new String("");
@Override
public void onReceive(Context context, Intent intent) {
/*
* Check for malformed intent (accept only DISMISS_ALARM_INTENT and
* ACTION_QUERY_CONDITION
*/
if (isDismissAlarmIntentValid(intent)) {
//Get the alarm label
_dismissedAlarmLabel = intent.getExtras().getString(Constants.DISMISS_ALARM_KEY_ALARM_LABEL);
Logger.Fine("Alarm is Being Dismissed: " + _dismissedAlarmLabel);
//Broadcast the Tasker requery event to finalize the event
context.sendBroadcast(INTENT_REQUEST_REQUERY);
} else if (isTaskerQueryConditionIntentValid(intent)) {
//Get the configured alarm label
final Bundle bundle = intent.getBundleExtra(com.twofortyfouram.locale.Intent.EXTRA_BUNDLE);
String configuredAlarmLabel = bundle.getString(Constants.DISMISS_ALARM_KEY_ALARM_LABEL);
Logger.Fine("Alarm Label to Validate Against Dismissed Alarm: " + configuredAlarmLabel);
//Determine if the event condition has been satisfied
boolean isEventConditionSatisfied = false;
if (configuredAlarmLabel.isEmpty()) {
isEventConditionSatisfied = true;
Logger.Fine("Satisfying Event Condition for Dismissed Alarm: Configured alarm label is empty");
} else if (_dismissedAlarmLabel.equals(configuredAlarmLabel)) {
isEventConditionSatisfied = true;
Logger.Fine("Satisfying Event Condition for Dismissed Alarm: " + configuredAlarmLabel);
}
//Determine if the event was satisfied or not
if (isEventConditionSatisfied) {
//Create a message for the satisfied dismissed alarm
final String toastMessage = context.getResources().getString(R.string.dismissed_alarm_satisfied, _dismissedAlarmLabel.isEmpty() ? "" : _dismissedAlarmLabel + " ");
Toast.makeText(context, toastMessage, Toast.LENGTH_LONG).show();
//Satisfy the Tasker event
setResultCode(com.twofortyfouram.locale.Intent.RESULT_CONDITION_SATISFIED);
} else {
Logger.Fine("Event Condition for Dismissed Alarm is Unsatisfied: " + _dismissedAlarmLabel + " != " + configuredAlarmLabel);
setResultCode(com.twofortyfouram.locale.Intent.RESULT_CONDITION_UNSATISFIED);
}
} else {
Logger.Error(String.format("Received Unexpected/Malformed Intent: " + intent.getAction()));
}
}
/**
* Determine if the dismiss alarm intent is valid
*
* @param intent Intent to check
* @return True if dismiss alarm intent is valid; false otherwise
*/
private final boolean isDismissAlarmIntentValid(Intent intent) {
//Ensure the intent is valid
if (intent != null) {
//Scrub the intent
BundleScrubber.scrub(intent);
//Verify the action is the dismiss alarm intent
if (Constants.DISMISS_ALARM_STATE_INTENT.equals(intent.getAction())) {
Logger.Fine("Dimiss Alarm State Intent Received");
//Ensure the bundle (extras) are valid
if (isDismissAlarmBundleValid(intent.getExtras())) {
//Dismiss alarm intent is valid
Logger.Fine("Dismiss Alarm Intent is Valid");
return true;
}
}
}
//Invalid dismiss alarm intent
return false;
}
/**
* Determine if the Tasker query condition intent is valid
*
* @param intent Intent to check
* @return True if Tasker query condition intent is valid; false otherwise
*/
private final boolean isTaskerQueryConditionIntentValid(Intent intent) {
//Ensure the intent is valid
if (intent != null) {
//Scrub the intent
BundleScrubber.scrub(intent);
//Verify the action is the Tasker query condition intent
if (com.twofortyfouram.locale.Intent.ACTION_QUERY_CONDITION.equals(intent.getAction())) {
Logger.Fine("Tasker Query Condition Intent Received");
//Ensure the bundle (extras) are valid
final Bundle bundle = intent.getBundleExtra(com.twofortyfouram.locale.Intent.EXTRA_BUNDLE);
if (isDismissAlarmBundleValid(bundle)) {
//Tasker query condition intent is valid
Logger.Fine("Tasker Query Condition Intent is Valid");
return true;
}
}
}
//Invalid Tasker query condition intent
return false;
}
/**
* Determine if the dismiss alarm bundle is valid. This is for the intent
* received via the Xposed method hook and from the Tasker query condition
* intent for configured plugin events.
*
* @param bundle Bundle to check
* @return True if dismiss alarm bundle is valid; false otherwise
*/
private final boolean isDismissAlarmBundleValid(Bundle bundle) {
//Ensure the bundle is valid
if (bundle != null) {
//Ensure the bundle contains the dismissed alarm label key
if (bundle.containsKey(Constants.DISMISS_ALARM_KEY_ALARM_LABEL)) {
//Ensure the size of the bundle (only one extra)
int bundleSize = bundle.keySet().size();
if (bundleSize == 1) {
//Dismiss alarm bundle is valid
Logger.Fine("Dismiss Alarm Bundle is Valid");
return true;
} else {
Logger.Warning("Invalid Dismissed Alarm Bundle: Bundle contains " + bundleSize + " keys; only one key is required");
}
} else {
Logger.Warning("Invalid Dismissed Alarm Bundle: Missing alarm label");
}
}
//Invalid dismiss alarm intent
return false;
}
}