Skip to content
This repository has been archived by the owner on Mar 25, 2024. It is now read-only.

Tasker Plugin #1435

Open
wants to merge 19 commits into
base: master
Choose a base branch
from
Open

Tasker Plugin #1435

wants to merge 19 commits into from

Conversation

christian-n
Copy link

Tasker Plugin

Features

  • Tasks over Intents
  • Task Service for scheduling
  • Event based tasks with threshold
  • Full-fledged user settings
  • Easy to implement

Implemeted devices

  • XWatch

Quickstart

To implement a device add a TaskerDevice like

    XWATCH(DeviceType.XWATCH, new XWatchTaskerSpec(DeviceType.XWATCH));

all you need is a DeviceType and a TaskerSpec. Last thing is to add the TaskerBleProfile to your AbstractBTLEDeviceSupport like

    addSupportedProfile(new TaskerBleProfile<>(this, TaskerDevice.XWATCH));

Note
If you want generic user settings you MUST extend AbstractTaskerSpec or atleast use PreferenceTaskerSettings as TaskerSettings.

Tasker Hook

Tasker hook is done with TaskerBleProfile as an AbstractBleProfile (correct me if this is not the best way).

Tasker Service

The AbstractTaskerService is used to schedule TaskerTask's. The threshold is used to cumulate calls. The TaskerEvent is then send with the specific amount of calls within that threshold.
The default service for the hook is SpecTaskerService.

It uses the TaskerSpec's TaskerSettings as configuration. There is a TaskerService implementation for programmatic use.

Tasker Event

The default TaskerEventType's are

  • Button: For button related events.
  • Connection: For bluetooth connection related events.
  • Data: For data receiving related events.
  • No_op: For non operational events.

You can easly add more types via TaskerEventType class. It does not effect the already implemented devices.
Don't forget to add your type to

    public static List<TaskerEventType> getTypes() {
        return Arrays.asList(BUTTON, CONNECTION, DATA);
    }

And for device support add it to the device's TaskerSpec

    List<TaskerEventType> getSupportedTypes();

Tasker Settings

Tasker user settings are implemented via

TaskerActivity

As main entry point from SettingsActivity. It lists TaskerDevice's and has a enabled preference for overall tasker support.
Forwards to TaskerEventsActivity.

TaskerEventsActivity

Scoped with TaskerDevice

Lists all event types from TaskerSpec's getSupportedTypes() method.
Forwards to TaskerEventActivity.

TaskerEventActivity

Scoped by TaskerDevice and TaskerEventType

Has preferences for

  • Enabling the events
  • Enabled the threshold
  • Setting the threshold
  • Setting a task name
  • Adding/Removing more tasks for threshold calls (like double button press)

ToDo

  • More devices should be implemented.
  • Only EN and DE is currently translated.

Commit Information

  • Includes JavaDoc

@cpfeiffer
Copy link
Contributor

Wow, that's very nice! I will review this (and some other PRs) tomorrow.

@cpfeiffer cpfeiffer self-assigned this Feb 21, 2019
@IzzySoft
Copy link
Collaborator

Though this might bring us the NonFreeAdd AntiFeature ("promoting" a non free app) at F-Droid, I can't wait to see this 😃

Copy link
Contributor

@cpfeiffer cpfeiffer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made it through the review 😄, looks great, thanks again 👌

Since I don't have an XWatch, I'll adapt it to the Bip to try it out. AFAICS it's just a few lines of code.

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: usually one uses instanceof instead of comparing the classes by identity. Otherwise it would be impossible for (technical) subclasses to be equal to the superclass. One example would be subclassing for testcases.

*
* @param <T> Bluetooth LE support class extends {@link AbstractBTLEDeviceSupport}
*/
public class TaskerBleProfile<T extends AbstractBTLEDeviceSupport> extends AbstractBleProfile<T> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is a very creative idea to make tasker support pluggable and reusable 😄

Subclasses of AbstractBleProfile are reusable implementations of BLE profiles (e.g. for setting time, alarms, heart rate, etc.).

This is rather an event handler that does no further BLE communication. Need to think&check if we can add an interface for that, in addition to the profiles without duplicating code (just thinking loud for now, no action required).

}

public TaskerEventType withIndex(int index) {
TaskerEventType taskerEventType = new TaskerEventType();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The builder-like approach (create().withIndex().withLocalization()) looks nice, but IMHO one or two constructors would be more sensible, since the events would be immutable then.

/**
* Creates a {@link android.widget.Toast} for the user to show that Tasker is enabled but no task is defined.
*/
public static void noTaskDefinedInformation() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use GB.toast() that does all the event loop handling (and logging in addition) for you.

return TaskerEventType.BUTTON;
}
if (data[0] == XWatchService.COMMAND_CONNECTED) {
return TaskerEventType.CONNECTION;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that such events would rather be handled generically via GBDevice#getState() changes (see GBDevice#sendDeviceUpdateEvent()).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The AbstractDeviceSupport#handleGBDeviceEvent() methods are probably also good candidates for a generic implementation.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you give me more info on that.

@christian-n
Copy link
Author

I will be on it tomorrow. Thanks for the review!

@christian-n
Copy link
Author

christian-n commented Mar 3, 2019

@cpfeiffer Ive done some of your fixes but i dont know what to do with getState.
Seems no one is using it. at least ive looked up the XWatchSupport and MiBandSupport.
And i could not find the method sendDeviceUpdateEvent()

@cpfeiffer
Copy link
Contributor

Thanks for the updates!

GBDevice#getState() is used all over the place. It's the state describing whether a device is disconnected, connected, initializing, busy, etc. I thought that these state changes would be good candidates for tasker interaction, especially since they could be handled in a device independent way.

The *Support-classes usually only set the state, but don't react to any changes.

@cpfeiffer
Copy link
Contributor

Please let me know if I should explain in more details.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
3 participants