diff --git a/app/build.gradle b/app/build.gradle
index 8b7abe2e0..893e36c2a 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -85,11 +85,6 @@ dependencies {
implementation "net.e175.klaus:solarpositioning:0.0.9"
// use pristine greendao instead of our custom version, since our custom jitpack-packaged
// version contains way too much and our custom patches are in the generator only.
-
- implementation 'com.twofortyfouram:android-plugin-client-sdk-for-locale:[4.0.3, 5.0['
- implementation 'com.twofortyfouram:android-plugin-host-sdk-for-locale:[2.0.3,3.0['
- implementation 'com.twofortyfouram:android-plugin-api-for-locale:[1.0.2,2.0['
-
implementation "org.greenrobot:greendao:2.2.1"
implementation "org.apache.commons:commons-lang3:3.7"
implementation "org.cyanogenmod:platform.sdk:6.0"
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index a02fe6631..958f3a737 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -515,26 +515,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/TaskerPlugin.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/TaskerPlugin.java
deleted file mode 100644
index 4c53e875b..000000000
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/TaskerPlugin.java
+++ /dev/null
@@ -1,1017 +0,0 @@
-/* Copyright (C) 2019 Daniel Dakhno
-
- This file is part of Gadgetbridge.
-
- Gadgetbridge is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Gadgetbridge 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 Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see . */
-package nodomain.freeyourgadget.gadgetbridge.devices.qhybrid;
-
-
-// Constants and functions for Tasker *extensions* to the plugin protocol
-// See Also: http://tasker.dinglisch.net/plugins.html
-
-// Release Notes
-
-// v1.1 20140202
-// added function variableNameValid()
-// fixed some javadoc entries (thanks to David Stone)
-
-// v1.2 20140211
-// added ACTION_EDIT_EVENT
-
-// v1.3 20140227
-// added REQUESTED_TIMEOUT_MS_NONE, REQUESTED_TIMEOUT_MS_MAX and REQUESTED_TIMEOUT_MS_NEVER
-// requestTimeoutMS(): added range check
-
-// v1.4 20140516
-// support for data pass through in REQUEST_QUERY intent
-// some javadoc entries fixed (thanks again David :-))
-
-// v1.5 20141120
-// added RESULT_CODE_FAILED_PLUGIN_FIRST
-// added Setting.VARNAME_ERROR_MESSAGE
-
-// v1.6 20150213
-// added Setting.getHintTimeoutMS()
-// added Host.addHintTimeoutMS()
-
-// v1.7 20160619
-// null check for getCallingActivity() in hostSupportsOnFireVariableReplacement( Activity editActivity )
-
-// v1.8 20161002
-// added hostSupportsKeyEncoding(), setKeyEncoding() and Host.getKeysWithEncoding()
-
-import java.net.URISyntaxException;
-import java.security.SecureRandom;
-import java.util.regex.Pattern;
-
-import android.app.Activity;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.net.Uri;
-import android.os.Bundle;
-import android.util.Log;
-
-public class TaskerPlugin {
-
- private final static String TAG = "TaskerPlugin";
-
- private final static String BASE_KEY = "net.dinglisch.android.tasker";
-
- private final static String EXTRAS_PREFIX = BASE_KEY + ".extras.";
-
- private final static int FIRST_ON_FIRE_VARIABLES_TASKER_VERSION = 80;
-
- public final static String VARIABLE_PREFIX = "%";
-
- // when generating non-repeating integers, look this far back for repeats
- // see getPositiveNonRepeatingRandomInteger()
- private final static int RANDOM_HISTORY_SIZE = 100;
-
- /**
- * Action that the EditActivity for an event plugin should be launched by
- */
- public final static String ACTION_EDIT_EVENT = BASE_KEY + ".ACTION_EDIT_EVENT";
-
- private final static String VARIABLE_NAME_START_EXPRESSION = "[\\w&&[^_]]";
- private final static String VARIABLE_NAME_MID_EXPRESSION = "[\\w0-9]+";
- private final static String VARIABLE_NAME_END_EXPRESSION = "[\\w0-9&&[^_]]";
-
- public final static String VARIABLE_NAME_MAIN_PART_MATCH_EXPRESSION =
- VARIABLE_NAME_START_EXPRESSION + VARIABLE_NAME_MID_EXPRESSION + VARIABLE_NAME_END_EXPRESSION
- ;
-
- public final static String VARIABLE_NAME_MATCH_EXPRESSION =
- VARIABLE_PREFIX + "+" +
- VARIABLE_NAME_MAIN_PART_MATCH_EXPRESSION
- ;
-
- private static Pattern VARIABLE_NAME_MATCH_PATTERN = null;
-
- /**
- * @see #addVariableBundle(Bundle, Bundle)
- * @see Host#getVariablesBundle(Bundle)
- */
- private final static String EXTRA_VARIABLES_BUNDLE = EXTRAS_PREFIX + "VARIABLES";
-
- /**
- * Host capabilities, passed to plugin with edit intents
- */
- private final static String EXTRA_HOST_CAPABILITIES = EXTRAS_PREFIX + "HOST_CAPABILITIES";
-
- /**
- * @see Setting#hostSupportsVariableReturn(Bundle)
- */
- public final static int EXTRA_HOST_CAPABILITY_SETTING_RETURN_VARIABLES = 2;
-
- /**
- * @see Condition#hostSupportsVariableReturn(Bundle)
- */
- public final static int EXTRA_HOST_CAPABILITY_CONDITION_RETURN_VARIABLES = 4;
-
- /**
- * @see Setting#hostSupportsOnFireVariableReplacement(Bundle)
- */
- public final static int EXTRA_HOST_CAPABILITY_SETTING_FIRE_VARIABLE_REPLACEMENT = 8;
-
- /**
- * @see Setting#hostSupportsVariableReturn(Bundle)
- */
- private final static int EXTRA_HOST_CAPABILITY_RELEVANT_VARIABLES = 16;
-
- public final static int EXTRA_HOST_CAPABILITY_SETTING_SYNCHRONOUS_EXECUTION = 32;
-
- public final static int EXTRA_HOST_CAPABILITY_REQUEST_QUERY_DATA_PASS_THROUGH = 64;
-
- public final static int EXTRA_HOST_CAPABILITY_ENCODING_JSON = 128;
-
- public final static int EXTRA_HOST_CAPABILITY_ALL =
- EXTRA_HOST_CAPABILITY_SETTING_RETURN_VARIABLES |
- EXTRA_HOST_CAPABILITY_CONDITION_RETURN_VARIABLES |
- EXTRA_HOST_CAPABILITY_SETTING_FIRE_VARIABLE_REPLACEMENT |
- EXTRA_HOST_CAPABILITY_RELEVANT_VARIABLES|
- EXTRA_HOST_CAPABILITY_SETTING_SYNCHRONOUS_EXECUTION |
- EXTRA_HOST_CAPABILITY_REQUEST_QUERY_DATA_PASS_THROUGH |
- EXTRA_HOST_CAPABILITY_ENCODING_JSON
- ;
-
- /**
- * Possible encodings of text in bundle values
- *
- * @see #setKeyEncoding(Bundle,String[],Encoding)
- */
- public enum Encoding { JSON };
-
- private final static String BUNDLE_KEY_ENCODING_JSON_KEYS = BASE_KEY + ".JSON_ENCODED_KEYS";
-
- public static boolean hostSupportsKeyEncoding( Bundle extrasFromHost, Encoding encoding ) {
- switch ( encoding ) {
- case JSON:
- return hostSupports( extrasFromHost, EXTRA_HOST_CAPABILITY_ENCODING_JSON );
- default:
- return false;
- }
- }
-
- /**
- *
- * Miscellaneous operational hints going one way or the other
- * @see Setting#hostSupportsVariableReturn(Bundle)
- */
-
- private final static String EXTRA_HINTS_BUNDLE = EXTRAS_PREFIX + "HINTS";
-
- private final static String BUNDLE_KEY_HINT_PREFIX = ".hints.";
-
- private final static String BUNDLE_KEY_HINT_TIMEOUT_MS = BUNDLE_KEY_HINT_PREFIX + "TIMEOUT";
-
- /**
- *
- * @see #hostSupportsRelevantVariables(Bundle)
- * @see #addRelevantVariableList(Intent, String[])
- * @see #getRelevantVariableList(Bundle)
- */
- private final static String BUNDLE_KEY_RELEVANT_VARIABLES = BASE_KEY + ".RELEVANT_VARIABLES";
-
- public static boolean hostSupportsRelevantVariables( Bundle extrasFromHost ) {
- return hostSupports( extrasFromHost, EXTRA_HOST_CAPABILITY_RELEVANT_VARIABLES );
- }
-
- /**
- * Specifies to host which variables might be used by the plugin.
- *
- * Used in EditActivity, before setResult().
- *
- * @param intentToHost the intent being returned to the host
- * @param variableNames array of relevant variable names
- */
- public static void addRelevantVariableList( Intent intentToHost, String [] variableNames ) {
- intentToHost.putExtra( BUNDLE_KEY_RELEVANT_VARIABLES, variableNames );
- }
-
- /**
- * Validate a variable name.
- *
- * The basic requirement for variables from a plugin is that they must be all lower-case.
- *
- * @param varName name to check
- */
- public static boolean variableNameValid( String varName ) {
-
- boolean validFlag = false;
-
- if ( varName == null )
- Log.d( TAG, "variableNameValid: null name" );
- else {
- if ( VARIABLE_NAME_MATCH_PATTERN == null )
- VARIABLE_NAME_MATCH_PATTERN = Pattern.compile( VARIABLE_NAME_MATCH_EXPRESSION, 0 );
-
- if ( VARIABLE_NAME_MATCH_PATTERN.matcher( varName ).matches() ) {
-
- if ( variableNameIsLocal( varName ) )
- validFlag = true;
- else
- Log.d( TAG, "variableNameValid: name not local: " + varName );
- }
- else
- Log.d( TAG, "variableNameValid: invalid name: " + varName );
- }
-
- return validFlag;
- }
-
- /**
- * Allows the plugin/host to indicate to each other a set of variables which they are referencing.
- * The host may use this to e.g. show a variable selection list in it's UI.
- * The host should use this if it previously indicated to the plugin that it supports relevant vars
- *
- * @param fromHostIntentExtras usually from getIntent().getExtras()
- * @return variableNames an array of relevant variable names
- */
- public static String [] getRelevantVariableList( Bundle fromHostIntentExtras ) {
-
- String [] relevantVars = (String []) getBundleValueSafe( fromHostIntentExtras, BUNDLE_KEY_RELEVANT_VARIABLES, String [].class, "getRelevantVariableList" );
-
- if ( relevantVars == null )
- relevantVars = new String [0];
-
- return relevantVars;
- }
-
- /**
- * Used by: plugin QueryReceiver, FireReceiver
- *
- * Add a bundle of variable name/value pairs.
- *
- * Names must be valid Tasker local variable names.
- * Values must be String, String [] or ArrayList
- * Null values cause deletion of possible already-existing variables
- * A null value where the variable does not already exist results in attempted deletion
- * of any existing array indices (%arr1, %arr2 etc)
- *
- * @param resultExtras the result extras from the receiver onReceive (from a call to getResultExtras())
- * @param variables the variables to send
- * @see Setting#hostSupportsVariableReturn(Bundle)
- * @see #variableNameValid(String)
- */
- public static void addVariableBundle( Bundle resultExtras, Bundle variables ) {
- resultExtras.putBundle( EXTRA_VARIABLES_BUNDLE, variables );
- }
-
- /**
- * Used by: plugin EditActivity
- *
- * Specify the encoding for a set of bundle keys.
- *
- * This is completely optional and currently only necessary if using Setting#setVariableReplaceKeys
- * where the corresponding values of some of the keys specified are JSON encoded.
- *
- * @param resultBundleToHost the bundle being returned to the host
- * @param keys the keys being returned to the host which are encoded in some way
- * @param encoding the encoding of the values corresponding to the specified keys
- * @see #setVariableReplaceKeys(Bundle,String[])
- * @see #hostSupportsKeyEncoding(Bundle, Encoding)
- */
- public static void setKeyEncoding( Bundle resultBundleToHost, String [] keys, Encoding encoding ) {
- if ( Encoding.JSON.equals( encoding ) )
- addStringArrayToBundleAsString(
- keys, resultBundleToHost, BUNDLE_KEY_ENCODING_JSON_KEYS, "setValueEncoding"
- );
- else
- Log.e( TAG, "unknown encoding: " + encoding );
- }
-
- // ----------------------------- SETTING PLUGIN ONLY --------------------------------- //
-
- public static class Setting {
-
- /**
- * Variable name into which a description of any error that occurred can be placed
- * for the user to process.
- *
- * Should *only* be set when the BroadcastReceiver result code indicates a failure.
- *
- * Note that the user needs to have configured the task to continue after failure of the plugin
- * action otherwise they will not be able to make use of the error message.
- *
- * For use with #addRelevantVariableList(Intent, String[]) and #addVariableBundle(Bundle, Bundle)
- *
- */
- public final static String VARNAME_ERROR_MESSAGE = VARIABLE_PREFIX + "errmsg";
-
- /**
- * @see #setVariableReplaceKeys(Bundle, String[])
- */
- private final static String BUNDLE_KEY_VARIABLE_REPLACE_STRINGS = EXTRAS_PREFIX + "VARIABLE_REPLACE_KEYS";
-
- /**
- * @see #requestTimeoutMS(android.content.Intent, int)
- */
- private final static String EXTRA_REQUESTED_TIMEOUT = EXTRAS_PREFIX + "REQUESTED_TIMEOUT";
-
- /**
- * @see #requestTimeoutMS(android.content.Intent, int)
- */
-
- public final static int REQUESTED_TIMEOUT_MS_NONE = 0;
-
- /**
- * @see #requestTimeoutMS(android.content.Intent, int)
- */
-
- public final static int REQUESTED_TIMEOUT_MS_MAX = 3599000;
-
- /**
- * @see #requestTimeoutMS(android.content.Intent, int)
- */
-
- public final static int REQUESTED_TIMEOUT_MS_NEVER = REQUESTED_TIMEOUT_MS_MAX + 1000;
-
- /**
- * @see #signalFinish(Context, Intent, int, Bundle)
- * @see Host#addCompletionIntent(Intent, Intent)
- */
- private final static String EXTRA_PLUGIN_COMPLETION_INTENT = EXTRAS_PREFIX + "COMPLETION_INTENT";
-
- /**
- * @see #signalFinish(Context, Intent, int, Bundle)
- * @see Host#getSettingResultCode(Intent)
- */
- public final static String EXTRA_RESULT_CODE = EXTRAS_PREFIX + "RESULT_CODE";
-
- /**
- * @see #signalFinish(Context, Intent, int, Bundle)
- * @see Host#getSettingResultCode(Intent)
- */
-
- public final static int RESULT_CODE_OK = Activity.RESULT_OK;
- public final static int RESULT_CODE_OK_MINOR_FAILURES = Activity.RESULT_FIRST_USER;
- public final static int RESULT_CODE_FAILED = Activity.RESULT_FIRST_USER + 1;
- public final static int RESULT_CODE_PENDING = Activity.RESULT_FIRST_USER + 2;
- public final static int RESULT_CODE_UNKNOWN = Activity.RESULT_FIRST_USER + 3;
-
- /**
- * If a plugin wants to define it's own error codes, start numbering them here.
- * The code will be placed in an error variable (%err in the case of Tasker) for
- * the user to process after the plugin action.
- */
-
- public final static int RESULT_CODE_FAILED_PLUGIN_FIRST = Activity.RESULT_FIRST_USER + 9;
-
- /**
- * Used by: plugin EditActivity.
- *
- * Indicates to plugin that host will replace variables in specified bundle keys.
- *
- * Replacement takes place every time the setting is fired, before the bundle is
- * passed to the plugin FireReceiver.
- *
- * @param extrasFromHost intent extras from the intent received by the edit activity
- * @see #setVariableReplaceKeys(Bundle, String[])
- */
- public static boolean hostSupportsOnFireVariableReplacement( Bundle extrasFromHost ) {
- return hostSupports( extrasFromHost, EXTRA_HOST_CAPABILITY_SETTING_FIRE_VARIABLE_REPLACEMENT );
- }
-
- /**
- * Used by: plugin EditActivity.
- *
- * Description as above.
- *
- * This version also includes backwards compatibility with pre 4.2 Tasker versions.
- * At some point this function will be deprecated.
- *
- * @param editActivity the plugin edit activity, needed to test calling Tasker version
- * @see #setVariableReplaceKeys(Bundle, String[])
- */
-
- public static boolean hostSupportsOnFireVariableReplacement( Activity editActivity ) {
-
- boolean supportedFlag = hostSupportsOnFireVariableReplacement( editActivity.getIntent().getExtras() );
-
- if ( ! supportedFlag ) {
-
- ComponentName callingActivity = editActivity.getCallingActivity();
-
- if ( callingActivity == null )
- Log.w( TAG, "hostSupportsOnFireVariableReplacement: null callingActivity, defaulting to false" );
- else {
- String callerPackage = callingActivity.getPackageName();
-
- // Tasker only supporteed this from 1.0.10
- supportedFlag =
- ( callerPackage.startsWith( BASE_KEY ) ) &&
- ( getPackageVersionCode( editActivity.getPackageManager(), callerPackage ) > FIRST_ON_FIRE_VARIABLES_TASKER_VERSION )
- ;
- }
- }
-
- return supportedFlag;
- }
-
- public static boolean hostSupportsSynchronousExecution( Bundle extrasFromHost ) {
- return hostSupports( extrasFromHost, EXTRA_HOST_CAPABILITY_SETTING_SYNCHRONOUS_EXECUTION );
- }
-
- /**
- * Request the host to wait the specified number of milliseconds before continuing.
- * Note that the host may choose to ignore the request.
- *
- * Maximum value is REQUESTED_TIMEOUT_MS_MAX.
- * Also available are REQUESTED_TIMEOUT_MS_NONE (continue immediately without waiting
- * for the plugin to finish) and REQUESTED_TIMEOUT_MS_NEVER (wait forever for
- * a result).
- *
- * Used in EditActivity, before setResult().
- *
- * @param intentToHost the intent being returned to the host
- * @param timeoutMS
- */
- public static void requestTimeoutMS( Intent intentToHost, int timeoutMS ) {
- if ( timeoutMS < 0 )
- Log.w( TAG, "requestTimeoutMS: ignoring negative timeout (" + timeoutMS + ")" );
- else {
- if (
- ( timeoutMS > REQUESTED_TIMEOUT_MS_MAX ) &&
- ( timeoutMS != REQUESTED_TIMEOUT_MS_NEVER )
- ) {
- Log.w( TAG, "requestTimeoutMS: requested timeout " + timeoutMS + " exceeds maximum, setting to max (" + REQUESTED_TIMEOUT_MS_MAX + ")" );
- timeoutMS = REQUESTED_TIMEOUT_MS_MAX;
- }
- intentToHost.putExtra( EXTRA_REQUESTED_TIMEOUT, timeoutMS );
- }
- }
-
- /**
- * Used by: plugin EditActivity
- *
- * Indicates to host which bundle keys should be replaced.
- *
- * @param resultBundleToHost the bundle being returned to the host
- * @param listOfKeyNames which bundle keys to replace variables in when setting fires
- * @see #hostSupportsOnFireVariableReplacement(Bundle)
- * @see #setKeyEncoding(Bundle,String[],Encoding)
- */
- public static void setVariableReplaceKeys( Bundle resultBundleToHost, String [] listOfKeyNames ) {
- addStringArrayToBundleAsString(
- listOfKeyNames, resultBundleToHost, BUNDLE_KEY_VARIABLE_REPLACE_STRINGS,
- "setVariableReplaceKeys"
- );
- }
-
- /**
- * Used by: plugin FireReceiver
- *
- * Indicates to plugin whether the host will process variables which it passes back
- *
- * @param extrasFromHost intent extras from the intent received by the FireReceiver
- * @see #signalFinish(Context, Intent, int, Bundle)
- */
- public static boolean hostSupportsVariableReturn( Bundle extrasFromHost ) {
- return hostSupports( extrasFromHost, EXTRA_HOST_CAPABILITY_SETTING_RETURN_VARIABLES );
- }
-
- /**
- * Used by: plugin FireReceiver
- *
- * Tell the host that the plugin has finished execution.
- *
- * This should only be used if RESULT_CODE_PENDING was returned by FireReceiver.onReceive().
- *
- * @param originalFireIntent the intent received from the host (via onReceive())
- * @param resultCode level of success in performing the settings
- * @param vars any variables that the plugin wants to set in the host
- * @see #hostSupportsSynchronousExecution(Bundle)
- */
- public static boolean signalFinish( Context context, Intent originalFireIntent, int resultCode, Bundle vars ) {
-
- String errorPrefix = "signalFinish: ";
-
- boolean okFlag = false;
-
- String completionIntentString = (String) getExtraValueSafe( originalFireIntent, Setting.EXTRA_PLUGIN_COMPLETION_INTENT, String.class, "signalFinish" );
-
- if ( completionIntentString != null ) {
-
- Uri completionIntentUri = null;
- try {
- completionIntentUri = Uri.parse( completionIntentString );
- }
- // should only throw NullPointer but don't particularly trust it
- catch ( Exception e ) {
- Log.w( TAG, errorPrefix + "couldn't parse " + completionIntentString );
- }
-
- if ( completionIntentUri != null ) {
- try {
- Intent completionIntent = Intent.parseUri( completionIntentString, Intent.URI_INTENT_SCHEME );
-
- completionIntent.putExtra( EXTRA_RESULT_CODE, resultCode );
-
- if ( vars != null )
- completionIntent.putExtra( EXTRA_VARIABLES_BUNDLE, vars );
-
- context.sendBroadcast( completionIntent );
-
- okFlag = true;
- }
- catch ( URISyntaxException e ) {
- Log.w( TAG, errorPrefix + "bad URI: " + completionIntentUri );
- }
- }
- }
-
- return okFlag;
- }
-
- /**
- * Check for a hint on the timeout value the host is using.
- * Used by: plugin FireReceiver.
- * Requires Tasker 4.7+
- *
- * @param extrasFromHost intent extras from the intent received by the FireReceiver
- * @return timeoutMS the hosts timeout setting for the action or -1 if no hint is available.
- *
- * @see #REQUESTED_TIMEOUT_MS_NONE, REQUESTED_TIMEOUT_MS_MAX, REQUESTED_TIMEOUT_MS_NEVER
- */
- public static int getHintTimeoutMS( Bundle extrasFromHost ) {
-
- int timeoutMS = -1;
-
- Bundle hintsBundle = (Bundle) TaskerPlugin.getBundleValueSafe( extrasFromHost, EXTRA_HINTS_BUNDLE, Bundle.class, "getHintTimeoutMS" );
-
- if ( hintsBundle != null ) {
-
- Integer val = (Integer) getBundleValueSafe( hintsBundle, BUNDLE_KEY_HINT_TIMEOUT_MS, Integer.class, "getHintTimeoutMS" );
-
- if ( val != null )
- timeoutMS = val;
- }
-
- return timeoutMS;
- }
- }
-
- // ----------------------------- CONDITION/EVENT PLUGIN ONLY --------------------------------- //
-
- public static class Condition {
-
- /**
- * Used by: plugin QueryReceiver
- *
- * Indicates to plugin whether the host will process variables which it passes back
- *
- * @param extrasFromHost intent extras from the intent received by the QueryReceiver
- * @see #addVariableBundle(Bundle, Bundle)
- */
- public static boolean hostSupportsVariableReturn( Bundle extrasFromHost ) {
- return hostSupports( extrasFromHost, EXTRA_HOST_CAPABILITY_CONDITION_RETURN_VARIABLES );
- }
- }
-
- // ----------------------------- EVENT PLUGIN ONLY --------------------------------- //
-
- public static class Event {
-
- public final static String PASS_THROUGH_BUNDLE_MESSAGE_ID_KEY = BASE_KEY + ".MESSAGE_ID";
-
- private final static String EXTRA_REQUEST_QUERY_PASS_THROUGH_DATA = EXTRAS_PREFIX + "PASS_THROUGH_DATA";
-
- /**
- * @param extrasFromHost intent extras from the intent received by the QueryReceiver
- * @see #addPassThroughData(Intent, Bundle)
- */
- public static boolean hostSupportsRequestQueryDataPassThrough( Bundle extrasFromHost ) {
- return hostSupports( extrasFromHost, EXTRA_HOST_CAPABILITY_REQUEST_QUERY_DATA_PASS_THROUGH );
- }
-
- /**
- * Specify a bundle of data (probably representing whatever change happened in the condition)
- * which will be included in the QUERY_CONDITION broadcast sent by the host for each
- * event instance of the plugin.
- *
- * The minimal purpose is to enable the plugin to associate a QUERY_CONDITION to the
- * with the REQUEST_QUERY that caused it.
- *
- * Note that for security reasons it is advisable to also store a message ID with the bundle
- * which can be compared to known IDs on receipt. The host cannot validate the source of
- * REQUEST_QUERY intents so fake data may be passed. Replay attacks are also possible.
- * addPassThroughMesssageID() can be used to add an ID if the plugin doesn't wish to add it's
- * own ID to the pass through bundle.
- *
- * Note also that there are several situations where REQUEST_QUERY will not result in a
- * QUERY_CONDITION intent (e.g. event throttling by the host), so plugin-local data
- * indexed with a message ID needs to be timestamped and eventually timed-out.
- *
- * This function can be called multiple times, each time all keys in data will be added to
- * that of previous calls.
- *
- * @param requestQueryIntent intent being sent to the host
- * @param data the data to be passed-through
- * @see #hostSupportsRequestQueryDataPassThrough(Bundle)
- * @see #retrievePassThroughData(Intent)
- * @see #addPassThroughMessageID
- *
- */
- public static void addPassThroughData( Intent requestQueryIntent, Bundle data ) {
-
- Bundle passThroughBundle = retrieveOrCreatePassThroughBundle( requestQueryIntent );
-
- passThroughBundle.putAll( data );
- }
-
- /**
- * Retrieve the pass through data from a QUERY_REQUEST from the host which was generated
- * by a REQUEST_QUERY from the plugin.
- *
- * Note that if addPassThroughMessageID() was previously called, the data will contain an extra
- * key TaskerPlugin.Event.PASS_THOUGH_BUNDLE_MESSAGE_ID_KEY.
- *
- * @param queryConditionIntent QUERY_REQUEST sent from host
- * @return data previously added to the REQUEST_QUERY intent
- * @see #hostSupportsRequestQueryDataPassThrough(Bundle)
- * @see #addPassThroughData(Intent,Bundle)
- */
- public static Bundle retrievePassThroughData( Intent queryConditionIntent ) {
- return (Bundle) getExtraValueSafe(
- queryConditionIntent,
- EXTRA_REQUEST_QUERY_PASS_THROUGH_DATA,
- Bundle.class,
- "retrievePassThroughData"
- );
- }
-
- /**
- * Add a message ID to a REQUEST_QUERY intent which will then be included in the corresponding
- * QUERY_CONDITION broadcast sent by the host for each event instance of the plugin.
- *
- * The minimal purpose is to enable the plugin to associate a QUERY_CONDITION to the
- * with the REQUEST_QUERY that caused it. It also allows the message to be verified
- * by the plugin to prevent e.g. replay attacks
- *
- * @param requestQueryIntent intent being sent to the host
- * @return a guaranteed non-repeating within 100 calls message ID
- * @see #hostSupportsRequestQueryDataPassThrough(Bundle)
- * @see #retrievePassThroughData(Intent)
- * @return an ID for the bundle so it can be identified and the caller verified when it is again received by the plugin
- *
- */
- public static int addPassThroughMessageID( Intent requestQueryIntent ) {
-
- Bundle passThroughBundle = retrieveOrCreatePassThroughBundle( requestQueryIntent );
-
- int id = getPositiveNonRepeatingRandomInteger();
-
- passThroughBundle.putInt( PASS_THROUGH_BUNDLE_MESSAGE_ID_KEY, id );
-
- return id;
- }
-
- /*
- * Retrieve the pass through data from a QUERY_REQUEST from the host which was generated
- * by a REQUEST_QUERY from the plugin.
- *
- * @param queryConditionIntent QUERY_REQUEST sent from host
- * @return the ID which was passed through by the host, or -1 if no ID was found
- * @see #hostSupportsRequestQueryDataPassThrough(Bundle)
- * @see #addPassThroughData(Intent,Bundle)
- */
- public static int retrievePassThroughMessageID( Intent queryConditionIntent ) {
-
- int toReturn = -1;
-
- Bundle passThroughData = Event.retrievePassThroughData( queryConditionIntent );
-
- if ( passThroughData != null ) {
- Integer id = (Integer) getBundleValueSafe(
- passThroughData,
- PASS_THROUGH_BUNDLE_MESSAGE_ID_KEY,
- Integer.class,
- "retrievePassThroughMessageID"
- );
-
- if ( id != null )
- toReturn = id;
- }
-
- return toReturn;
- }
-
- // internal use
- private static Bundle retrieveOrCreatePassThroughBundle( Intent requestQueryIntent ) {
-
- Bundle passThroughBundle;
-
- if ( requestQueryIntent.hasExtra( EXTRA_REQUEST_QUERY_PASS_THROUGH_DATA ) )
- passThroughBundle = requestQueryIntent.getBundleExtra( EXTRA_REQUEST_QUERY_PASS_THROUGH_DATA );
- else {
- passThroughBundle = new Bundle();
- requestQueryIntent.putExtra( EXTRA_REQUEST_QUERY_PASS_THROUGH_DATA, passThroughBundle );
- }
-
- return passThroughBundle;
- }
- }
- // ---------------------------------- HOST ----------------------------------------- //
-
- public static class Host {
-
- /**
- * Tell the plugin what capabilities the host support. This should be called when sending
- * intents to any EditActivity, FireReceiver or QueryReceiver.
- *
- * @param toPlugin the intent we're sending
- * @return capabilities one or more of the EXTRA_HOST_CAPABILITY_XXX flags
- */
- public static Intent addCapabilities( Intent toPlugin, int capabilities ) {
- return toPlugin.putExtra( EXTRA_HOST_CAPABILITIES, capabilities );
- }
-
- /**
- * Add an intent to the fire intent before it goes to the plugin FireReceiver, which the plugin
- * can use to signal when it is finished. Only use if @code{pluginWantsSychronousExecution} is true.
- *
- * @param fireIntent fire intent going to the plugin
- * @param completionIntent intent which will signal the host that the plugin is finished.
- * Implementation is host-dependent.
- */
- public static void addCompletionIntent( Intent fireIntent, Intent completionIntent ) {
- fireIntent.putExtra(
- Setting.EXTRA_PLUGIN_COMPLETION_INTENT,
- completionIntent.toUri( Intent.URI_INTENT_SCHEME )
- );
- }
-
- /**
- * When a setting plugin is finished, it sends the host the intent which was passed to it
- * via @code{addCompletionIntent}.
- *
- * @param completionIntent intent returned from the plugin when it finished.
- * @return resultCode measure of plugin success, defaults to UNKNOWN
- */
- public static int getSettingResultCode( Intent completionIntent ) {
-
- Integer val = (Integer) getExtraValueSafe( completionIntent, Setting.EXTRA_RESULT_CODE, Integer.class, "getSettingResultCode" );
-
- return ( val == null ) ? Setting.RESULT_CODE_UNKNOWN : val;
- }
-
- /**
- * Extract a bundle of variables from an intent received from the FireReceiver. This
- * should be called if the host previously indicated to the plugin
- * that it supports setting variable return.
- *
- * @param resultExtras getResultExtras() from BroadcastReceiver:onReceive()
- * @return variables a bundle of variable name/value pairs
- * @see #addCapabilities(Intent, int)
- */
-
- public static Bundle getVariablesBundle( Bundle resultExtras ) {
- return (Bundle) getBundleValueSafe(
- resultExtras, EXTRA_VARIABLES_BUNDLE, Bundle.class, "getVariablesBundle"
- );
- }
-
- /**
- * Inform a setting plugin of the timeout value the host is using.
- *
- * @param toPlugin the intent we're sending
- * @param timeoutMS the hosts timeout setting for the action. Note that this may differ from
- * that which the plugin requests.
- * @see #REQUESTED_TIMEOUT_MS_NONE, REQUESTED_TIMEOUT_MS_MAX, REQUESTED_TIMEOUT_MS_NEVER
- */
- public static void addHintTimeoutMS( Intent toPlugin, int timeoutMS ) {
- getHintsBundle( toPlugin, "addHintTimeoutMS" ).putInt( BUNDLE_KEY_HINT_TIMEOUT_MS, timeoutMS );
- }
-
- private static Bundle getHintsBundle( Intent intent, String funcName ) {
-
- Bundle hintsBundle = (Bundle) getExtraValueSafe( intent, EXTRA_HINTS_BUNDLE, Bundle.class, funcName );
-
- if ( hintsBundle == null ) {
- hintsBundle = new Bundle();
- intent.putExtra( EXTRA_HINTS_BUNDLE, hintsBundle );
- }
-
- return hintsBundle;
- }
-
- public static boolean haveRequestedTimeout( Bundle extrasFromPluginEditActivity ) {
- return extrasFromPluginEditActivity.containsKey( Setting.EXTRA_REQUESTED_TIMEOUT );
- }
-
- public static int getRequestedTimeoutMS( Bundle extrasFromPluginEditActivity ) {
- return
- (Integer) getBundleValueSafe(
- extrasFromPluginEditActivity, Setting.EXTRA_REQUESTED_TIMEOUT, Integer.class, "getRequestedTimeout"
- )
- ;
- }
-
- public static String [] getSettingVariableReplaceKeys( Bundle fromPluginEditActivity ) {
- return getStringArrayFromBundleString(
- fromPluginEditActivity, Setting.BUNDLE_KEY_VARIABLE_REPLACE_STRINGS,
- "getSettingVariableReplaceKeys"
- );
- }
-
- public static String [] getKeysWithEncoding( Bundle fromPluginEditActivity, Encoding encoding ) {
-
- String [] toReturn = null;
-
- if ( Encoding.JSON.equals( encoding ) )
- toReturn = getStringArrayFromBundleString(
- fromPluginEditActivity, TaskerPlugin.BUNDLE_KEY_ENCODING_JSON_KEYS,
- "getKeyEncoding:JSON"
- );
- else
- Log.w( TAG, "Host.getKeyEncoding: unknown encoding " + encoding );
-
- return toReturn;
- }
-
- public static boolean haveRelevantVariables( Bundle b ) {
- return b.containsKey( BUNDLE_KEY_RELEVANT_VARIABLES );
- }
-
- public static void cleanRelevantVariables( Bundle b ) {
- b.remove( BUNDLE_KEY_RELEVANT_VARIABLES );
- }
-
- public static void cleanHints( Bundle extras ) {
- extras.remove( TaskerPlugin.EXTRA_HINTS_BUNDLE );
- }
-
- public static void cleanRequestedTimeout( Bundle extras ) {
- extras.remove( Setting.EXTRA_REQUESTED_TIMEOUT );
- }
-
- public static void cleanSettingReplaceVariables( Bundle b ) {
- b.remove( Setting.BUNDLE_KEY_VARIABLE_REPLACE_STRINGS );
- }
- }
-
- // ---------------------------------- HELPER FUNCTIONS -------------------------------- //
-
- private static Object getBundleValueSafe( Bundle b, String key, Class> expectedClass, String funcName ) {
- Object value = null;
-
- if ( b != null ) {
- if ( b.containsKey( key ) ) {
- Object obj = b.get( key );
- if ( obj == null )
- Log.w( TAG, funcName + ": " + key + ": null value" );
- else if ( obj.getClass() != expectedClass )
- Log.w( TAG, funcName + ": " + key + ": expected " + expectedClass.getClass().getName() + ", got " + obj.getClass().getName() );
- else
- value = obj;
- }
- }
- return value;
- }
-
- private static Object getExtraValueSafe( Intent i, String key, Class> expectedClass, String funcName ) {
- return ( i.hasExtra( key ) ) ?
- getBundleValueSafe( i.getExtras(), key, expectedClass, funcName ) :
- null;
- }
-
- private static boolean hostSupports( Bundle extrasFromHost, int capabilityFlag ) {
- Integer flags = (Integer) getBundleValueSafe( extrasFromHost, EXTRA_HOST_CAPABILITIES, Integer.class, "hostSupports" );
- return
- ( flags != null ) &&
- ( ( flags & capabilityFlag ) > 0 )
- ;
- }
-
- public static int getPackageVersionCode( PackageManager pm, String packageName ) {
-
- int code = -1;
-
- if ( pm != null ) {
- try {
- PackageInfo pi = pm.getPackageInfo( packageName, 0 );
- if ( pi != null )
- code = pi.versionCode;
- }
- catch ( Exception e ) {
- Log.e( TAG, "getPackageVersionCode: exception getting package info" );
- }
- }
-
- return code;
- }
-
- private static boolean variableNameIsLocal( String varName ) {
-
- int digitCount = 0;
- int length = varName.length();
-
- for ( int x = 0; x < length; x++ ) {
- char ch = varName.charAt( x );
-
- if ( Character.isUpperCase( ch ) )
- return false;
- else if ( Character.isDigit( ch ) )
- digitCount++;
- }
-
- if ( digitCount == ( varName.length() - 1 ) )
- return false;
-
- return true;
- }
-
- private static String [] getStringArrayFromBundleString( Bundle bundle, String key, String funcName ) {
-
- String spec = (String) getBundleValueSafe( bundle, key, String.class, funcName );
-
- String [] toReturn = null;
-
- if ( spec != null )
- toReturn = spec.split( " " );
-
- return toReturn;
- }
-
- private static void addStringArrayToBundleAsString( String [] toAdd, Bundle bundle, String key, String callerName ) {
-
- StringBuilder builder = new StringBuilder();
-
- if ( toAdd != null ) {
-
- for ( String keyName : toAdd ) {
-
- if ( keyName.contains( " " ) )
- Log.w( TAG, callerName + ": ignoring bad keyName containing space: " + keyName );
- else {
- if ( builder.length() > 0 )
- builder.append( ' ' );
-
- builder.append( keyName );
- }
-
- if ( builder.length() > 0 )
- bundle.putString( key, builder.toString() );
- }
- }
- }
-
- // state tracking for random number sequence
- private static int [] lastRandomsSeen = null;
- private static int randomInsertPointer = 0;
- private static SecureRandom sr = null;
-
- /**
- * Generate a sequence of secure random positive integers which is guaranteed not to repeat
- * in the last 100 calls to this function.
- *
- * @return a random positive integer
- */
- public static int getPositiveNonRepeatingRandomInteger() {
-
- // initialize on first call
- if ( sr == null ) {
- sr = new SecureRandom();
- lastRandomsSeen = new int[RANDOM_HISTORY_SIZE];
-
- for ( int x = 0; x < lastRandomsSeen.length; x++ )
- lastRandomsSeen[x] = -1;
- }
-
- int toReturn;
- do {
- // pick a number
- toReturn = sr.nextInt( Integer.MAX_VALUE );
-
- // check we havn't see it recently
- for ( int seen : lastRandomsSeen ) {
- if ( seen == toReturn ) {
- toReturn = -1;
- break;
- }
- }
- }
- while ( toReturn == -1 );
-
- // update history
- lastRandomsSeen[randomInsertPointer] = toReturn;
- randomInsertPointer = ( randomInsertPointer + 1 ) % lastRandomsSeen.length;
-
- return toReturn;
- }
-
-}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/TaskerPluginActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/TaskerPluginActivity.java
deleted file mode 100644
index d3f8b8a5d..000000000
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/TaskerPluginActivity.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/* Copyright (C) 2019 Daniel Dakhno
-
- This file is part of Gadgetbridge.
-
- Gadgetbridge is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Gadgetbridge 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 Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see . */
-package nodomain.freeyourgadget.gadgetbridge.devices.qhybrid;
-
-import android.content.Intent;
-import android.os.Bundle;
-import android.widget.EditText;
-import android.widget.RadioButton;
-import android.widget.RadioGroup;
-import android.widget.TextView;
-
-import com.twofortyfouram.locale.sdk.client.ui.activity.AbstractPluginActivity;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import nodomain.freeyourgadget.gadgetbridge.R;
-import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.PlayNotificationRequest;
-
-public class TaskerPluginActivity extends AbstractPluginActivity {
- public static final String key_hours = "qhybrid_hours";
- public static final String key_minute = "qhybrid_minutes";
- public static final String key_vibration = "qhybrid_vibration";
-
- RadioGroup group;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_tasker_plugin);
-
- group = findViewById(R.id.qhybrid_tasker_vibration);
- for(PlayNotificationRequest.VibrationType type : PlayNotificationRequest.VibrationType.values()){
- RadioButton button = new RadioButton(this);
- button.setText(type.name() + " (" + type.name() + ")");
- button.setId(type.getValue());
- group.addView(button);
- }
- group.check(PlayNotificationRequest.VibrationType.NO_VIBE.getValue());
- RadioButton custom = new RadioButton(this);
- custom.setText("variable %vibration");
- custom.setId(10);
- group.addView(custom);
-
- Intent intent = getIntent();
- if(intent.hasExtra(key_hours)){
- ((TextView) findViewById(R.id.qhybrid_hour_degrees)).setText(intent.getStringExtra(key_hours));
- }
- if(intent.hasExtra(key_minute)){
- ((TextView) findViewById(R.id.qhybrid_minute_degrees)).setText(intent.getStringExtra(key_minute));
- }
- if(intent.hasExtra(key_vibration)){
- String vibe = intent.getStringExtra(key_vibration);
- if(vibe.equals("%vibration")){
- group.check(10);
- }else {
- group.check(Integer.parseInt(vibe));
- }
- }
- }
-
- @Override
- public boolean isBundleValid(@NonNull Bundle bundle) {
- return true;
- }
-
- @Override
- public void onPostCreateWithPreviousResult(@NonNull Bundle bundle, @NonNull String s) {
-
- }
-
- @Nullable
- @Override
- public Bundle getResultBundle() {
- int vibration = group.getCheckedRadioButtonId();
-
- Bundle bundle = new Bundle();
- bundle.putString(key_hours, ((EditText) findViewById(R.id.qhybrid_hour_degrees)).getText().toString());
- bundle.putString(key_minute, ((EditText) findViewById(R.id.qhybrid_minute_degrees)).getText().toString());
-
- if(vibration == 10){
- bundle.putString(key_vibration, "%vibration");
- }else{
- bundle.putString(key_vibration, String.valueOf(vibration));
- }
- TaskerPlugin.Setting.setVariableReplaceKeys(bundle, new String[]{key_hours, key_minute, key_vibration});
-
- return bundle;
- }
-
- @NonNull
- @Override
- public String getResultBlurb(@NonNull Bundle bundle) {
- return "nope";
- }
-}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/TaskerPluginReceiver.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/TaskerPluginReceiver.java
deleted file mode 100644
index 5d7241406..000000000
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/TaskerPluginReceiver.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/* Copyright (C) 2019 Daniel Dakhno
-
- This file is part of Gadgetbridge.
-
- Gadgetbridge is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Gadgetbridge 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 Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see . */
-package nodomain.freeyourgadget.gadgetbridge.devices.qhybrid;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-
-import androidx.localbroadcastmanager.content.LocalBroadcastManager;
-import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport;
-import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.PlayNotificationRequest;
-
-public class TaskerPluginReceiver extends BroadcastReceiver {
-
- @Override
- public void onReceive(Context context, Intent intent) {
- String min = intent.getStringExtra(TaskerPluginActivity.key_minute);
- String hour = intent.getStringExtra(TaskerPluginActivity.key_hours);
- String vibration = intent.getStringExtra(TaskerPluginActivity.key_vibration);
-
- int minDegrees = (int)Float.parseFloat(min);
- int hourDegrees = (int)Float.parseFloat(hour);
-
- NotificationConfiguration config = new NotificationConfiguration(
- (short)minDegrees,
- (short)hourDegrees,
- null,
- null,
- false,
- PlayNotificationRequest.VibrationType.fromValue(Byte.parseByte(vibration))
- );
-
- Intent send = new Intent(QHybridSupport.QHYBRID_COMMAND_NOTIFICATION);
- send.putExtra("CONFIG", config);
- LocalBroadcastManager.getInstance(context).sendBroadcast(send);
- }
-}
diff --git a/app/src/main/res/layout/activity_tasker_plugin.xml b/app/src/main/res/layout/activity_tasker_plugin.xml
deleted file mode 100644
index de35d6215..000000000
--- a/app/src/main/res/layout/activity_tasker_plugin.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 964245529..5db09d28e 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -757,7 +757,6 @@
Calibrate
Watch 9 pairing
Watch 9 calibration
- Play Q Hybrid notification
Contextual Arabic
Enable this to support contextual Arabic
Right To Left Support