Remove FeatureFlag.IncomingShare

This commit is contained in:
Benoit Marty 2025-08-12 12:53:02 +02:00 committed by Benoit Marty
parent a1c36d9afa
commit 3e73496c85
9 changed files with 1 additions and 172 deletions

View file

@ -147,14 +147,6 @@
<data android:host="user" />
<data android:host="room" />
</intent-filter>
</activity>
<!-- Using an activity-alias for incoming share intent, in order
to be able to disable the feature programmatically -->
<activity-alias
android:name=".ShareActivity"
android:exported="true"
android:targetActivity=".MainActivity">
<!-- Incoming share simple -->
<intent-filter>
<action android:name="android.intent.action.SEND" />
@ -171,7 +163,7 @@
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.OPENABLE" />
</intent-filter>
</activity-alias>
</activity>
<provider
android:name="androidx.core.content.FileProvider"

View file

@ -63,7 +63,6 @@ dependencies {
testImplementation(projects.features.networkmonitor.test)
testImplementation(projects.tests.testutils)
testImplementation(projects.features.rageshake.test)
testImplementation(projects.features.share.test)
testImplementation(projects.services.appnavstate.test)
testImplementation(projects.services.analytics.test)
testImplementation(libs.test.appyx.junit)

View file

@ -14,7 +14,6 @@ import androidx.compose.runtime.getValue
import im.vector.app.features.analytics.plan.SuperProperties
import io.element.android.features.rageshake.api.crash.CrashDetectionState
import io.element.android.features.rageshake.api.detection.RageshakeDetectionState
import io.element.android.features.share.api.ShareService
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.matrix.api.SdkMetadata
import io.element.android.services.analytics.api.AnalyticsService
@ -26,7 +25,6 @@ class RootPresenter @Inject constructor(
private val rageshakeDetectionPresenter: Presenter<RageshakeDetectionState>,
private val appErrorStateService: AppErrorStateService,
private val analyticsService: AnalyticsService,
private val shareService: ShareService,
private val sdkMetadata: SdkMetadata,
) : Presenter<RootState> {
@Composable
@ -45,10 +43,6 @@ class RootPresenter @Inject constructor(
)
}
LaunchedEffect(Unit) {
shareService.observeFeatureFlag(this)
}
return RootState(
rageshakeDetectionState = rageshakeDetectionState,
crashDetectionState = crashDetectionState,

View file

@ -14,16 +14,12 @@ import com.google.common.truth.Truth.assertThat
import io.element.android.appnav.root.RootPresenter
import io.element.android.features.rageshake.api.crash.aCrashDetectionState
import io.element.android.features.rageshake.api.detection.aRageshakeDetectionState
import io.element.android.features.share.api.ShareService
import io.element.android.features.share.test.FakeShareService
import io.element.android.libraries.matrix.test.FakeSdkMetadata
import io.element.android.services.analytics.test.FakeAnalyticsService
import io.element.android.services.apperror.api.AppErrorState
import io.element.android.services.apperror.api.AppErrorStateService
import io.element.android.services.apperror.impl.DefaultAppErrorStateService
import io.element.android.tests.testutils.WarmUpRule
import io.element.android.tests.testutils.lambda.lambdaRecorder
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.test.runTest
import org.junit.Rule
import org.junit.Test
@ -43,22 +39,6 @@ class RootPresenterTest {
}
}
@Test
fun `present - check that share service is invoked`() = runTest {
val lambda = lambdaRecorder<CoroutineScope, Unit> { _ -> }
val presenter = createRootPresenter(
shareService = FakeShareService {
lambda(it)
}
)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
skipItems(1)
lambda.assertions().isCalledOnce()
}
}
@Test
fun `present - passes app error state`() = runTest {
val presenter = createRootPresenter(
@ -82,14 +62,12 @@ class RootPresenterTest {
private fun createRootPresenter(
appErrorService: AppErrorStateService = DefaultAppErrorStateService(),
shareService: ShareService = FakeShareService {},
): RootPresenter {
return RootPresenter(
crashDetectionPresenter = { aCrashDetectionState() },
rageshakeDetectionPresenter = { aRageshakeDetectionState() },
appErrorStateService = appErrorService,
analyticsService = FakeAnalyticsService(),
shareService = shareService,
sdkMetadata = FakeSdkMetadata("sha")
)
}

View file

@ -1,14 +0,0 @@
/*
* Copyright 2024 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.features.share.api
import kotlinx.coroutines.CoroutineScope
interface ShareService {
fun observeFeatureFlag(coroutineScope: CoroutineScope)
}

View file

@ -1,74 +0,0 @@
/*
* Copyright 2024 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.features.share.impl
import android.content.ComponentName
import android.content.Context
import android.content.pm.PackageManager
import com.squareup.anvil.annotations.ContributesBinding
import io.element.android.features.share.api.ShareService
import io.element.android.libraries.di.AppScope
import io.element.android.libraries.di.ApplicationContext
import io.element.android.libraries.featureflag.api.FeatureFlagService
import io.element.android.libraries.featureflag.api.FeatureFlags
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import timber.log.Timber
import javax.inject.Inject
@ContributesBinding(AppScope::class)
class DefaultShareService @Inject constructor(
private val featureFlagService: FeatureFlagService,
@ApplicationContext private val context: Context,
) : ShareService {
override fun observeFeatureFlag(coroutineScope: CoroutineScope) {
val shareActivityComponent = getShareActivityComponent()
?: return Unit.also {
Timber.w("ShareActivity not found")
}
featureFlagService.isFeatureEnabledFlow(FeatureFlags.IncomingShare)
.onEach { enabled ->
shareActivityComponent.enableOrDisable(enabled)
}
.launchIn(coroutineScope)
}
private fun getShareActivityComponent(): ComponentName? {
return context.packageManager
.getPackageInfo(
context.packageName,
PackageManager.GET_ACTIVITIES or PackageManager.MATCH_DISABLED_COMPONENTS
)
.activities
?.firstOrNull { it.name.endsWith(".ShareActivity") }
?.let { shareActivityInfo ->
ComponentName(
shareActivityInfo.packageName,
shareActivityInfo.name,
)
}
}
private fun ComponentName.enableOrDisable(enabled: Boolean) {
val state = if (enabled) {
PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
} else {
PackageManager.COMPONENT_ENABLED_STATE_DISABLED
}
try {
context.packageManager.setComponentEnabledSetting(
this,
state,
PackageManager.DONT_KILL_APP,
)
} catch (e: Exception) {
Timber.e(e, "Failed to enable or disable the component")
}
}
}

View file

@ -1,19 +0,0 @@
/*
* Copyright 2024 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/
plugins {
id("io.element.android-library")
}
android {
namespace = "io.element.android.features.share.test"
}
dependencies {
implementation(projects.features.share.api)
implementation(libs.coroutines.core)
implementation(projects.tests.testutils)
}

View file

@ -1,20 +0,0 @@
/*
* Copyright 2024 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.features.share.test
import io.element.android.features.share.api.ShareService
import io.element.android.tests.testutils.lambda.lambdaError
import kotlinx.coroutines.CoroutineScope
class FakeShareService(
private val observeFeatureFlagLambda: (CoroutineScope) -> Unit = { lambdaError() }
) : ShareService {
override fun observeFeatureFlag(coroutineScope: CoroutineScope) {
observeFeatureFlagLambda(coroutineScope)
}
}

View file

@ -82,13 +82,6 @@ enum class FeatureFlags(
defaultValue = { OnBoardingConfig.CAN_LOGIN_WITH_QR_CODE },
isFinished = false,
),
IncomingShare(
key = "feature.incomingShare",
title = "Incoming Share support",
description = "Allow the application to receive data from other applications",
defaultValue = { true },
isFinished = false,
),
PinnedEvents(
key = "feature.pinnedEvents",
title = "Pinned Events",