Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ enum class ActionType {
CHANGE_COUNTER,
/** Send a notification. */
NOTIFICATION,
/** Press the Android back button using accessibility services. */
BACK_BUTTON,
}


Expand Down Expand Up @@ -156,4 +158,4 @@ enum class IntentExtraType {
FLOAT,
SHORT,
STRING
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -364,9 +364,24 @@ internal open class CompatDeserializer : Deserializer {
ActionType.TOGGLE_EVENT -> deserializeActionToggleEvent(jsonAction)
ActionType.CHANGE_COUNTER -> deserializeActionChangeCounter(jsonAction)
ActionType.NOTIFICATION -> deserializeActionNotification(jsonAction)
ActionType.BACK_BUTTON -> deserializeActionBackButton(jsonAction)
null -> null
}

@VisibleForTesting(otherwise = VisibleForTesting.PROTECTED)
open fun deserializeActionBackButton(jsonBackButton: JsonObject): ActionEntity? {
val id = jsonBackButton.getLong("id", true) ?: return null
val eventId = jsonBackButton.getLong("eventId", true) ?: return null

return ActionEntity(
id = id,
eventId = eventId,
name = jsonBackButton.getString("name") ?: "",
priority = jsonBackButton.getInt("priority")?.coerceAtLeast(0) ?: 0,
type = ActionType.BACK_BUTTON,
)
}

@VisibleForTesting(otherwise = VisibleForTesting.PROTECTED)
open fun deserializeActionClick(
jsonClick: JsonObject,
Expand Down Expand Up @@ -588,4 +603,4 @@ internal open class CompatDeserializer : Deserializer {

return EventToggleEntity(id, actionId, type, toggleEventId)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ interface SmartActionExecutor : AndroidExecutor {
/** Send a notification defined by the provided NotificationRequest. */
fun executeNotification(notification: NotificationRequest)

/** Press the Android back button using accessibility services. */
fun executeBackButton()

/** Request to reset any state related to action execution, most likely because a new session is starting. */
fun clearState()
}
Expand All @@ -42,4 +45,4 @@ data class NotificationRequest(
val message: String,
val groupName: String,
val importance: Int,
)
)
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,6 @@ sealed class Action : Identifiable, Completable, Prioritizable {
is Swipe -> copy(id = id, eventId = eventId, name = name, priority = priority)
is ToggleEvent -> copy(id = id, eventId = eventId, name = name, priority = priority)
is Notification -> copy(id = id, eventId = eventId, name = name, priority = priority)
is BackButton -> copy(id = id, eventId = eventId, name = name, priority = priority)
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
/*
* Copyright (C) 2024 Kevin Buzeau
*
*
* This program 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.
*
*
* This program 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/>.
*/
Expand Down Expand Up @@ -43,6 +43,7 @@ internal fun Action.toEntity(): ActionEntity {
is ToggleEvent -> toToggleEventEntity()
is ChangeCounter -> toChangeCounterEntity()
is Notification -> toNotificationEntity()
is BackButton -> toBackButtonEntity()
}
}

Expand Down Expand Up @@ -151,8 +152,25 @@ internal fun CompleteActionEntity.toDomain(cleanIds: Boolean = false): Action =
ActionType.TOGGLE_EVENT -> toDomainToggleEvent(cleanIds)
ActionType.CHANGE_COUNTER -> toDomainChangeCounter(cleanIds)
ActionType.NOTIFICATION -> toDomainNotification(cleanIds)
ActionType.BACK_BUTTON -> toDomainBackButton(cleanIds)
}

private fun BackButton.toBackButtonEntity(): ActionEntity =
ActionEntity(
id = id.databaseId,
eventId = eventId.databaseId,
priority = priority,
name = name!!,
type = ActionType.BACK_BUTTON,
)

private fun CompleteActionEntity.toDomainBackButton(cleanIds: Boolean = false) = BackButton(
id = Identifier(id = action.id, asTemporary = cleanIds),
eventId = Identifier(id = action.eventId, asTemporary = cleanIds),
name = action.name,
priority = action.priority,
)

private fun CompleteActionEntity.toDomainClick(cleanIds: Boolean = false) = Click(
id = Identifier(id = action.id, asTemporary = cleanIds),
eventId = Identifier(id = action.eventId, asTemporary = cleanIds),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright (C) 2024 Kevin Buzeau
*
* This program 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.
*
* This program 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/>.
*/
package com.buzbuz.smartautoclicker.core.domain.model.action

import com.buzbuz.smartautoclicker.core.base.identifier.Identifier

/** Press the Android back button using accessibility services. */
data class BackButton(
override val id: Identifier,
override val eventId: Identifier,
override val name: String?,
override var priority: Int,
) : Action() {

override fun hashCodeNoIds(): Int {
var result = name?.hashCode() ?: 0
result = 31 * result + priority
return result
}

override fun deepCopy(): Action = copy()
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import com.buzbuz.smartautoclicker.core.domain.model.action.Pause
import com.buzbuz.smartautoclicker.core.domain.model.action.Swipe
import com.buzbuz.smartautoclicker.core.domain.model.action.ToggleEvent
import com.buzbuz.smartautoclicker.core.domain.model.action.ChangeCounter
import com.buzbuz.smartautoclicker.core.domain.model.action.BackButton
import com.buzbuz.smartautoclicker.core.domain.model.action.Notification
import com.buzbuz.smartautoclicker.core.domain.model.action.intent.putDomainExtra
import com.buzbuz.smartautoclicker.core.domain.model.event.Event
Expand Down Expand Up @@ -95,6 +96,7 @@ internal class ActionExecutor(
is ToggleEvent -> executeToggleEvent(action)
is ChangeCounter -> executeChangeCounter(action)
is Notification -> executeNotification(event, action)
is BackButton -> withContext(Dispatchers.Main) { androidExecutor.executeBackButton() }
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
/*
* Copyright (C) 2024 Kevin Buzeau
*
*
* This program 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.
*
*
* This program 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/>.
*/
Expand All @@ -26,6 +26,7 @@ import com.buzbuz.smartautoclicker.core.base.identifier.IdentifierCreator
import com.buzbuz.smartautoclicker.core.domain.IRepository
import com.buzbuz.smartautoclicker.core.domain.model.CounterOperationValue
import com.buzbuz.smartautoclicker.core.domain.model.action.Action
import com.buzbuz.smartautoclicker.core.domain.model.action.BackButton
import com.buzbuz.smartautoclicker.core.domain.model.action.ChangeCounter
import com.buzbuz.smartautoclicker.core.domain.model.action.Click
import com.buzbuz.smartautoclicker.core.domain.model.action.Click.PositionType
Expand Down Expand Up @@ -303,6 +304,14 @@ class EditedItemsBuilder internal constructor(
priority = 0,
)

fun createNewBackButton(context: Context): BackButton =
BackButton(
id = actionsIdCreator.generateNewIdentifier(),
eventId = getEditedEventIdOrThrow(),
name = defaultValues.backButtonName(context),
priority = 0,
)

fun createNewActionFrom(from: Action, eventId: Identifier = getEditedEventIdOrThrow()): Action = when (from) {
is Click -> createNewClickFrom(from, eventId)
is Swipe -> createNewSwipeFrom(from, eventId)
Expand All @@ -311,6 +320,7 @@ class EditedItemsBuilder internal constructor(
is ToggleEvent -> createNewToggleEventFrom(from, eventId)
is ChangeCounter -> createNewChangeCounterFrom(from, eventId)
is Notification -> createNewNotificationFrom(from, eventId)
is BackButton -> createNewBackButtonFrom(from, eventId)
}

private fun createNewClickFrom(from: Click, eventId: Identifier): Click {
Expand All @@ -327,6 +337,13 @@ class EditedItemsBuilder internal constructor(
)
}

private fun createNewBackButtonFrom(from: BackButton, eventId: Identifier): BackButton =
from.copy(
id = actionsIdCreator.generateNewIdentifier(),
eventId = eventId,
name = "" + from.name,
)

private fun createNewSwipeFrom(from: Swipe, eventId: Identifier): Swipe =
from.copy(
id = actionsIdCreator.generateNewIdentifier(),
Expand Down Expand Up @@ -425,4 +442,4 @@ class EditedItemsBuilder internal constructor(
?: throw IllegalStateException("Can't create items without an edited action")

private fun getEditedImageEventsCountOrThrow(): Int = editor.getEditedImageEventsCount()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,12 @@ internal class EditionDefaultValues(private val scenarioRepository: IRepository)
fun notificationName(context: Context): String =
context.getString(R.string.default_notification_name)

fun backButtonName(context: Context): String =
context.getString(R.string.item_back_button_title)

fun counterComparisonOperation(): TriggerCondition.OnCounterCountReached.ComparisonOperation =
TriggerCondition.OnCounterCountReached.ComparisonOperation.EQUALS

private fun isTutorialModeEnabled(): Boolean =
scenarioRepository.isTutorialModeEnabled()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import com.buzbuz.smartautoclicker.core.common.overlays.base.BaseOverlay
import com.buzbuz.smartautoclicker.core.common.permissions.model.PermissionPostNotification
import com.buzbuz.smartautoclicker.feature.smart.config.ui.common.starters.RequestNotificationPermissionActivity
import com.buzbuz.smartautoclicker.core.domain.model.action.Action
import com.buzbuz.smartautoclicker.core.domain.model.action.BackButton
import com.buzbuz.smartautoclicker.core.domain.model.action.ChangeCounter
import com.buzbuz.smartautoclicker.core.domain.model.action.Click
import com.buzbuz.smartautoclicker.core.domain.model.action.Intent
Expand Down Expand Up @@ -102,7 +103,11 @@ internal fun BaseOverlay.showActionConfigDialog(configurator: ActionConfigurator
if (PermissionPostNotification().checkIfGranted(context)) NotificationDialog(actionConfigDialogListener)
else newNotificationPermissionStarterOverlay(context)
}
else -> throw IllegalArgumentException("Not yet supported")
is BackButton -> {
configurator.upsertEditedAction()
return
}
else -> throw IllegalArgumentException("Unsupported action type")
}


Expand All @@ -111,4 +116,4 @@ internal fun BaseOverlay.showActionConfigDialog(configurator: ActionConfigurator
newOverlay = overlay,
hideCurrent = true,
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ class SmartActionsBriefViewModel @Inject constructor(
add(ActionTypeChoice.ToggleEvent)
add(ActionTypeChoice.Notification)
add(ActionTypeChoice.Intent)
add(ActionTypeChoice.BackButton)
}
}.stateIn(viewModelScope, SharingStarted.Eagerly, emptyList())

Expand Down Expand Up @@ -169,6 +170,7 @@ class SmartActionsBriefViewModel @Inject constructor(
ActionTypeChoice.ToggleEvent -> editionRepository.editedItemsBuilder.createNewToggleEvent(context)
ActionTypeChoice.ChangeCounter -> editionRepository.editedItemsBuilder.createNewChangeCounter(context)
ActionTypeChoice.Notification -> editionRepository.editedItemsBuilder.createNewNotification(context)
ActionTypeChoice.BackButton -> editionRepository.editedItemsBuilder.createNewBackButton(context)
ActionTypeChoice.Copy -> throw IllegalArgumentException("Unsupported action type for creation $choice")
}

Expand Down Expand Up @@ -326,4 +328,4 @@ class SmartActionsBriefViewModel @Inject constructor(
private data class BriefVisualizationState(
val focusedIndex: Int,
val gestureCaptureStarted: Boolean,
)
)
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package com.buzbuz.smartautoclicker.feature.smart.config.ui.action.selection

import com.buzbuz.smartautoclicker.core.common.overlays.dialog.implementation.DialogChoice
import com.buzbuz.smartautoclicker.feature.smart.config.R
import com.buzbuz.smartautoclicker.feature.smart.config.ui.common.model.action.getBackButtonIconRes
import com.buzbuz.smartautoclicker.feature.smart.config.ui.common.model.action.getChangeCounterIconRes
import com.buzbuz.smartautoclicker.feature.smart.config.ui.common.model.action.getClickIconRes
import com.buzbuz.smartautoclicker.feature.smart.config.ui.common.model.action.getIntentIconRes
Expand Down Expand Up @@ -88,4 +89,11 @@ sealed class ActionTypeChoice(
R.string.item_notification_desc,
getNotificationIconRes(),
)
}

/** Back Button Action choice. */
data object BackButton : ActionTypeChoice(
R.string.item_back_button_title,
R.string.item_back_button_desc,
getBackButtonIconRes(),
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package com.buzbuz.smartautoclicker.feature.smart.config.ui.common.model.action
import android.content.Context
import androidx.annotation.DrawableRes
import com.buzbuz.smartautoclicker.core.domain.model.action.Action
import com.buzbuz.smartautoclicker.core.domain.model.action.BackButton
import com.buzbuz.smartautoclicker.core.domain.model.action.ChangeCounter
import com.buzbuz.smartautoclicker.core.domain.model.action.Click
import com.buzbuz.smartautoclicker.core.domain.model.action.Intent
Expand Down Expand Up @@ -55,6 +56,7 @@ internal fun Action.getIconRes(): Int = when (this) {
is ToggleEvent -> getToggleEventIconRes()
is ChangeCounter -> getChangeCounterIconRes()
is Notification -> getNotificationIconRes()
is BackButton -> getBackButtonIconRes()
else -> throw IllegalArgumentException("Not yet supported")
}

Expand All @@ -66,5 +68,6 @@ internal fun Action.getActionDescription(context: Context, parent: Event, inErro
is ToggleEvent -> getDescription(context, inError)
is ChangeCounter -> getDescription(context, inError)
is Notification -> getDescription(context, inError)
is BackButton -> getDescription(context)
else -> throw IllegalArgumentException("Not yet supported")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright (C) 2024 Kevin Buzeau
*
* This program 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.
*
* This program 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/>.
*/
package com.buzbuz.smartautoclicker.feature.smart.config.ui.common.model.action

import android.content.Context
import androidx.annotation.DrawableRes
import com.buzbuz.smartautoclicker.core.domain.model.action.BackButton
import com.buzbuz.smartautoclicker.feature.smart.config.R


@DrawableRes
internal fun getBackButtonIconRes(): Int = R.drawable.ic_back

internal fun BackButton.getDescription(context: Context): String =
context.getString(R.string.item_back_button_details)
Loading