diff options
| author | 2024-03-20 01:26:12 +0000 | |
|---|---|---|
| committer | 2024-03-20 01:26:12 +0000 | |
| commit | 48a676de11407883af5d0ce2d90587819d89ce08 (patch) | |
| tree | 535663f3561430142ae85710c5b7bd4abafff95a /java | |
| parent | e8b42e069661ebf8f143edda6d5c82ab39fc67f0 (diff) | |
| parent | d24b4164f1b8f4fb9378463b0ca87fcb288a18d4 (diff) | |
Merge "Fix erroneous selection callback invocation." into main
Diffstat (limited to 'java')
8 files changed, 98 insertions, 34 deletions
diff --git a/java/src/com/android/intentresolver/contentpreview/payloadtoggle/data/model/SelectionRecord.kt b/java/src/com/android/intentresolver/contentpreview/payloadtoggle/data/model/SelectionRecord.kt new file mode 100644 index 00000000..c8fcb9d5 --- /dev/null +++ b/java/src/com/android/intentresolver/contentpreview/payloadtoggle/data/model/SelectionRecord.kt @@ -0,0 +1,30 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.intentresolver.contentpreview.payloadtoggle.data.model + +import com.android.intentresolver.contentpreview.payloadtoggle.shared.model.PreviewModel + +data class SelectionRecord( + val type: SelectionRecordType, + val selection: Set<PreviewModel>, +) + +enum class SelectionRecordType { + Uninitialized, + Initial, + Updated, +} diff --git a/java/src/com/android/intentresolver/contentpreview/payloadtoggle/data/model/TargetIntentRecord.kt b/java/src/com/android/intentresolver/contentpreview/payloadtoggle/data/model/TargetIntentRecord.kt new file mode 100644 index 00000000..17393023 --- /dev/null +++ b/java/src/com/android/intentresolver/contentpreview/payloadtoggle/data/model/TargetIntentRecord.kt @@ -0,0 +1,21 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.intentresolver.contentpreview.payloadtoggle.data.model + +import android.content.Intent + +data class TargetIntentRecord(val isInitial: Boolean, val intent: Intent) diff --git a/java/src/com/android/intentresolver/contentpreview/payloadtoggle/data/repository/PreviewSelectionsRepository.kt b/java/src/com/android/intentresolver/contentpreview/payloadtoggle/data/repository/PreviewSelectionsRepository.kt index 2d849d14..b461d10b 100644 --- a/java/src/com/android/intentresolver/contentpreview/payloadtoggle/data/repository/PreviewSelectionsRepository.kt +++ b/java/src/com/android/intentresolver/contentpreview/payloadtoggle/data/repository/PreviewSelectionsRepository.kt @@ -17,12 +17,16 @@ package com.android.intentresolver.contentpreview.payloadtoggle.data.repository import android.util.Log +import com.android.intentresolver.contentpreview.payloadtoggle.data.model.SelectionRecord +import com.android.intentresolver.contentpreview.payloadtoggle.data.model.SelectionRecordType.Initial +import com.android.intentresolver.contentpreview.payloadtoggle.data.model.SelectionRecordType.Uninitialized +import com.android.intentresolver.contentpreview.payloadtoggle.data.model.SelectionRecordType.Updated import com.android.intentresolver.contentpreview.payloadtoggle.shared.model.PreviewModel import dagger.hilt.android.scopes.ViewModelScoped import javax.inject.Inject -import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.filterNotNull +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.update private const val TAG = "PreviewSelectionsRep" @@ -30,32 +34,34 @@ private const val TAG = "PreviewSelectionsRep" /** Stores set of selected previews. */ @ViewModelScoped class PreviewSelectionsRepository @Inject constructor() { - /** Set of selected previews. */ - private val _selections = MutableStateFlow<Set<PreviewModel>?>(null) + private val _selections = MutableStateFlow(SelectionRecord(Uninitialized, emptySet())) - val selections: Flow<Set<PreviewModel>> = _selections.filterNotNull() + /** Selected previews data */ + val selections: StateFlow<SelectionRecord> = _selections.asStateFlow() fun setSelection(selection: Set<PreviewModel>) { - _selections.value = selection + _selections.value = SelectionRecord(Initial, selection) } fun select(item: PreviewModel) { - _selections.update { selection -> - selection?.let { it + item } - ?: run { - Log.w(TAG, "Changing selection before it is initialized") - null - } + _selections.update { record -> + if (record.type == Uninitialized) { + Log.w(TAG, "Changing selection before it is initialized") + record + } else { + SelectionRecord(Updated, record.selection + item) + } } } fun unselect(item: PreviewModel) { - _selections.update { selection -> - selection?.let { it - item } - ?: run { - Log.w(TAG, "Changing selection before it is initialized") - null - } + _selections.update { record -> + if (record.type == Uninitialized) { + Log.w(TAG, "Changing selection before it is initialized") + record + } else { + SelectionRecord(Updated, record.selection - item) + } } } } diff --git a/java/src/com/android/intentresolver/contentpreview/payloadtoggle/data/repository/TargetIntentRepository.kt b/java/src/com/android/intentresolver/contentpreview/payloadtoggle/data/repository/TargetIntentRepository.kt index c8436846..bb43323a 100644 --- a/java/src/com/android/intentresolver/contentpreview/payloadtoggle/data/repository/TargetIntentRepository.kt +++ b/java/src/com/android/intentresolver/contentpreview/payloadtoggle/data/repository/TargetIntentRepository.kt @@ -18,6 +18,7 @@ package com.android.intentresolver.contentpreview.payloadtoggle.data.repository import android.content.Intent import com.android.intentresolver.contentpreview.payloadtoggle.data.model.CustomActionModel +import com.android.intentresolver.contentpreview.payloadtoggle.data.model.TargetIntentRecord import com.android.intentresolver.inject.TargetIntent import dagger.hilt.android.scopes.ViewModelScoped import javax.inject.Inject @@ -31,10 +32,14 @@ constructor( @TargetIntent initialIntent: Intent, initialActions: List<CustomActionModel>, ) { - val targetIntent = MutableStateFlow(initialIntent) + val targetIntent = MutableStateFlow(TargetIntentRecord(isInitial = true, initialIntent)) // TODO: this can probably be derived from [targetIntent]; right now, the [initialActions] are // coming from a different place (ChooserRequest) than later ones (SelectionChangeCallback) // and so this serves as the source of truth between the two. val customActions = MutableStateFlow(initialActions) + + fun updateTargetIntent(intent: Intent) { + targetIntent.value = TargetIntentRecord(isInitial = false, intent) + } } diff --git a/java/src/com/android/intentresolver/contentpreview/payloadtoggle/domain/interactor/SelectablePreviewInteractor.kt b/java/src/com/android/intentresolver/contentpreview/payloadtoggle/domain/interactor/SelectablePreviewInteractor.kt index 0b1038f5..3b5b0ddf 100644 --- a/java/src/com/android/intentresolver/contentpreview/payloadtoggle/domain/interactor/SelectablePreviewInteractor.kt +++ b/java/src/com/android/intentresolver/contentpreview/payloadtoggle/domain/interactor/SelectablePreviewInteractor.kt @@ -30,8 +30,7 @@ class SelectablePreviewInteractor( val uri: Uri = key.uri /** Whether or not this preview is selected by the user. */ - val isSelected: Flow<Boolean> - get() = selectionRepo.selections.map { key in it } + val isSelected: Flow<Boolean> = selectionRepo.selections.map { key in it.selection } /** Sets whether this preview is selected by the user. */ fun setSelected(isSelected: Boolean) { diff --git a/java/src/com/android/intentresolver/contentpreview/payloadtoggle/domain/interactor/SelectionInteractor.kt b/java/src/com/android/intentresolver/contentpreview/payloadtoggle/domain/interactor/SelectionInteractor.kt index ee9bd689..0b8bcdd7 100644 --- a/java/src/com/android/intentresolver/contentpreview/payloadtoggle/domain/interactor/SelectionInteractor.kt +++ b/java/src/com/android/intentresolver/contentpreview/payloadtoggle/domain/interactor/SelectionInteractor.kt @@ -24,9 +24,8 @@ import kotlinx.coroutines.flow.map class SelectionInteractor @Inject constructor( - private val selectionRepo: PreviewSelectionsRepository, + selectionRepo: PreviewSelectionsRepository, ) { /** Amount of selected previews. */ - val amountSelected: Flow<Int> - get() = selectionRepo.selections.map { it.size } + val amountSelected: Flow<Int> = selectionRepo.selections.map { it.selection.size } } diff --git a/java/src/com/android/intentresolver/contentpreview/payloadtoggle/domain/interactor/UpdateTargetIntentInteractor.kt b/java/src/com/android/intentresolver/contentpreview/payloadtoggle/domain/interactor/UpdateTargetIntentInteractor.kt index 4cb1f5b6..3ce9aaff 100644 --- a/java/src/com/android/intentresolver/contentpreview/payloadtoggle/domain/interactor/UpdateTargetIntentInteractor.kt +++ b/java/src/com/android/intentresolver/contentpreview/payloadtoggle/domain/interactor/UpdateTargetIntentInteractor.kt @@ -18,6 +18,7 @@ package com.android.intentresolver.contentpreview.payloadtoggle.domain.interactor +import com.android.intentresolver.contentpreview.payloadtoggle.data.model.SelectionRecordType import com.android.intentresolver.contentpreview.payloadtoggle.data.repository.ChooserParamsUpdateRepository import com.android.intentresolver.contentpreview.payloadtoggle.data.repository.PreviewSelectionsRepository import com.android.intentresolver.contentpreview.payloadtoggle.data.repository.TargetIntentRepository @@ -31,6 +32,7 @@ import javax.inject.Inject import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.flow.collectLatest +import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.filterNotNull import kotlinx.coroutines.flow.mapLatest import kotlinx.coroutines.launch @@ -50,7 +52,8 @@ constructor( suspend fun launch(): Unit = coroutineScope { launch { intentRepository.targetIntent - .mapLatest { targetIntent -> selectionCallback.onSelectionChanged(targetIntent) } + .filter { !it.isInitial } + .mapLatest { record -> selectionCallback.onSelectionChanged(record.intent) } .filterNotNull() .collect { updates -> val actions = updates.customActions ?: emptyList() @@ -60,9 +63,13 @@ constructor( } } launch { - selectionRepo.selections.collectLatest { - intentRepository.targetIntent.value = targetIntentModifier.onSelectionChanged(it) - } + selectionRepo.selections + .filter { it.type == SelectionRecordType.Updated } + .collectLatest { + intentRepository.updateTargetIntent( + targetIntentModifier.onSelectionChanged(it.selection) + ) + } } } } diff --git a/java/src/com/android/intentresolver/v2/domain/interactor/ChooserRequestUpdateInteractor.kt b/java/src/com/android/intentresolver/v2/domain/interactor/ChooserRequestUpdateInteractor.kt index 534b2be3..871701cf 100644 --- a/java/src/com/android/intentresolver/v2/domain/interactor/ChooserRequestUpdateInteractor.kt +++ b/java/src/com/android/intentresolver/v2/domain/interactor/ChooserRequestUpdateInteractor.kt @@ -22,7 +22,6 @@ import com.android.intentresolver.contentpreview.payloadtoggle.data.repository.C import com.android.intentresolver.contentpreview.payloadtoggle.data.repository.TargetIntentRepository import com.android.intentresolver.contentpreview.payloadtoggle.domain.model.ShareouselUpdate import com.android.intentresolver.inject.ChooserServiceFlags -import com.android.intentresolver.inject.TargetIntent import com.android.intentresolver.v2.ui.model.ActivityModel import com.android.intentresolver.v2.ui.model.ChooserRequest import com.android.intentresolver.v2.ui.viewmodel.readChooserRequest @@ -36,6 +35,7 @@ import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.filterNotNull +import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch @@ -47,7 +47,6 @@ class ChooserRequestUpdateInteractor @AssistedInject constructor( private val activityModel: ActivityModel, - @TargetIntent private val initialIntent: Intent, private val targetIntentRepository: TargetIntentRepository, private val paramsUpdateRepository: ChooserParamsUpdateRepository, // TODO: replace with a proper repository, when available @@ -59,10 +58,8 @@ constructor( coroutineScope { launch { targetIntentRepository.targetIntent - // TODO: maybe find a better way to exclude the initial intent (as here it's - // compared by - // reference) - .filter { it !== initialIntent } + .filter { !it.isInitial } + .map { it.intent } .collect(::updateTargetIntent) } |