Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b307d4e5 authored by Abhishek Aggarwal's avatar Abhishek Aggarwal Committed by Abhishek Aggarwal
Browse files

feat(domain): add source-aware update eligibility primitives

parent d75b43e3
Loading
Loading
Loading
Loading
+87 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2026 e Foundation
 *
 * 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 <https://www.gnu.org/licenses/>.
 *
 */

package foundation.e.apps.domain.updates

import foundation.e.apps.domain.model.install.Status
import javax.inject.Inject

class GetUpdateEligibilityUseCase @Inject constructor() {

    data class Request(
        val renderedSource: UpdateSource,
        val rawStatus: Status,
        val trustedStore: TrustedStore,
        val isThirdPartyUpdatesEnabled: Boolean,
        val ownership: UpdateOwnership?,
        val isPwa: Boolean = false,
    )

    fun displayStatus(request: Request): Status {
        return when (invoke(request)) {
            UpdateEligibility.ELIGIBLE,
            UpdateEligibility.NOT_UPDATABLE -> request.rawStatus
            UpdateEligibility.BLOCKED_BY_THIRD_PARTY_POLICY,
            UpdateEligibility.WRONG_SOURCE,
            UpdateEligibility.UNVERIFIED -> Status.INSTALLED
        }
    }

    operator fun invoke(request: Request): UpdateEligibility {
        if (request.rawStatus != Status.UPDATABLE) return UpdateEligibility.NOT_UPDATABLE
        if (request.isPwa || request.renderedSource == UpdateSource.NEUTRAL) {
            return UpdateEligibility.ELIGIBLE
        }

        return when (request.trustedStore) {
            TrustedStore.APP_LOUNGE -> UpdateEligibility.ELIGIBLE
            TrustedStore.TRUSTED_NEUTRAL -> UpdateEligibility.ELIGIBLE
            TrustedStore.PLAY_STORE -> ifSourceMatches(request.renderedSource, UpdateSource.PLAY_STORE)
            TrustedStore.OPEN_SOURCE -> ifSourceMatches(request.renderedSource, UpdateSource.OPEN_SOURCE)
            TrustedStore.NON_TRUSTED -> resolveNonTrustedEligibility(
                renderedSource = request.renderedSource,
                isThirdPartyUpdatesEnabled = request.isThirdPartyUpdatesEnabled,
                ownership = request.ownership,
            )
        }
    }

    private fun ifSourceMatches(
        rendered: UpdateSource,
        expected: UpdateSource,
    ): UpdateEligibility {
        return if (rendered == expected) UpdateEligibility.ELIGIBLE else UpdateEligibility.WRONG_SOURCE
    }

    private fun resolveNonTrustedEligibility(
        renderedSource: UpdateSource,
        isThirdPartyUpdatesEnabled: Boolean,
        ownership: UpdateOwnership?,
    ): UpdateEligibility {
        if (!isThirdPartyUpdatesEnabled) {
            return UpdateEligibility.BLOCKED_BY_THIRD_PARTY_POLICY
        }

        return when {
            ownership == null -> UpdateEligibility.UNVERIFIED
            ownership.owns(renderedSource) -> UpdateEligibility.ELIGIBLE
            ownership.isVerified -> UpdateEligibility.WRONG_SOURCE
            else -> UpdateEligibility.UNVERIFIED
        }
    }
}
+27 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2026 e Foundation
 *
 * 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 <https://www.gnu.org/licenses/>.
 *
 */

package foundation.e.apps.domain.updates

enum class TrustedStore {
    APP_LOUNGE,
    PLAY_STORE,
    OPEN_SOURCE,
    TRUSTED_NEUTRAL,
    NON_TRUSTED,
}
+27 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2026 e Foundation
 *
 * 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 <https://www.gnu.org/licenses/>.
 *
 */

package foundation.e.apps.domain.updates

enum class UpdateEligibility {
    ELIGIBLE,
    BLOCKED_BY_THIRD_PARTY_POLICY,
    WRONG_SOURCE,
    UNVERIFIED,
    NOT_UPDATABLE,
}
+38 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2026 e Foundation
 *
 * 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 <https://www.gnu.org/licenses/>.
 *
 */

package foundation.e.apps.domain.updates

enum class UpdateOwnership {
    OPEN_SOURCE_OWNED,
    PLAY_STORE_OWNED,
    MULTI_SOURCE_OWNED,
    UNVERIFIED,
    ;

    val isVerified: Boolean
        get() = this != UNVERIFIED

    fun owns(source: UpdateSource): Boolean {
        return when (source) {
            UpdateSource.OPEN_SOURCE -> this == OPEN_SOURCE_OWNED || this == MULTI_SOURCE_OWNED
            UpdateSource.PLAY_STORE -> this == PLAY_STORE_OWNED || this == MULTI_SOURCE_OWNED
            UpdateSource.NEUTRAL -> false
        }
    }
}
+25 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2026 e Foundation
 *
 * 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 <https://www.gnu.org/licenses/>.
 *
 */

package foundation.e.apps.domain.updates

enum class UpdateSource {
    OPEN_SOURCE,
    PLAY_STORE,
    NEUTRAL,
}
Loading