1 /* <lambda>null2 * Copyright (C) 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.intentresolver.inject 18 19 import android.content.Intent 20 import android.net.Uri 21 import android.service.chooser.ChooserAction 22 import androidx.lifecycle.SavedStateHandle 23 import com.android.intentresolver.data.model.ChooserRequest 24 import com.android.intentresolver.ui.model.ActivityModel 25 import com.android.intentresolver.ui.viewmodel.readChooserRequest 26 import com.android.intentresolver.util.ownedByCurrentUser 27 import com.android.intentresolver.validation.Valid 28 import com.android.intentresolver.validation.ValidationResult 29 import dagger.Module 30 import dagger.Provides 31 import dagger.hilt.InstallIn 32 import dagger.hilt.android.components.ViewModelComponent 33 import dagger.hilt.android.scopes.ViewModelScoped 34 import javax.inject.Qualifier 35 36 @Module 37 @InstallIn(ViewModelComponent::class) 38 object ActivityModelModule { 39 @Provides 40 fun provideActivityModel(savedStateHandle: SavedStateHandle): ActivityModel = 41 requireNotNull(savedStateHandle[ActivityModel.ACTIVITY_MODEL_KEY]) { 42 "ActivityModel missing in SavedStateHandle! (${ActivityModel.ACTIVITY_MODEL_KEY})" 43 } 44 45 @Provides 46 @ChooserIntent 47 fun chooserIntent(activityModel: ActivityModel): Intent = activityModel.intent 48 49 @Provides 50 @ViewModelScoped 51 fun provideInitialRequest( 52 activityModel: ActivityModel, 53 flags: ChooserServiceFlags, 54 ): ValidationResult<ChooserRequest> = readChooserRequest(activityModel, flags) 55 56 @Provides 57 fun provideChooserRequest( 58 initialRequest: ValidationResult<ChooserRequest>, 59 ): ChooserRequest = 60 requireNotNull((initialRequest as? Valid)?.value) { 61 "initialRequest is Invalid, no chooser request available" 62 } 63 64 @Provides 65 @TargetIntent 66 fun targetIntent(chooserReq: ValidationResult<ChooserRequest>): Intent = 67 requireNotNull((chooserReq as? Valid)?.value?.targetIntent) { "no target intent available" } 68 69 @Provides 70 fun customActions(chooserReq: ValidationResult<ChooserRequest>): List<ChooserAction> = 71 requireNotNull((chooserReq as? Valid)?.value?.chooserActions) { 72 "no chooser actions available" 73 } 74 75 @Provides 76 @ViewModelScoped 77 @ContentUris 78 fun selectedUris(chooserRequest: ValidationResult<ChooserRequest>): List<Uri> = 79 requireNotNull((chooserRequest as? Valid)?.value?.targetIntent?.contentUris?.toList()) { 80 "no selected uris available" 81 } 82 83 @Provides 84 @FocusedItemIndex 85 fun focusedItemIndex(chooserReq: ValidationResult<ChooserRequest>): Int = 86 requireNotNull((chooserReq as? Valid)?.value?.focusedItemPosition) { 87 "no focused item position available" 88 } 89 90 @Provides 91 @AdditionalContent 92 fun additionalContentUri(chooserReq: ValidationResult<ChooserRequest>): Uri = 93 requireNotNull((chooserReq as? Valid)?.value?.additionalContentUri) { 94 "no additional content uri available" 95 } 96 } 97 98 @Qualifier 99 @MustBeDocumented 100 @Retention(AnnotationRetention.RUNTIME) 101 annotation class FocusedItemIndex 102 103 @Qualifier 104 @MustBeDocumented 105 @Retention(AnnotationRetention.RUNTIME) 106 annotation class AdditionalContent 107 108 @Qualifier @MustBeDocumented @Retention(AnnotationRetention.RUNTIME) annotation class ChooserIntent 109 110 @Qualifier @MustBeDocumented @Retention(AnnotationRetention.RUNTIME) annotation class ContentUris 111 112 @Qualifier @MustBeDocumented @Retention(AnnotationRetention.RUNTIME) annotation class TargetIntent 113 114 private val Intent.contentUris: Sequence<Uri> <lambda>null115 get() = sequence { 116 if (Intent.ACTION_SEND == action) { 117 getParcelableExtra(Intent.EXTRA_STREAM, Uri::class.java) 118 ?.takeIf { it.ownedByCurrentUser } 119 ?.let { yield(it) } 120 } else { 121 getParcelableArrayListExtra(Intent.EXTRA_STREAM, Uri::class.java)?.forEach { uri -> 122 if (uri.ownedByCurrentUser) { 123 yield(uri) 124 } 125 } 126 } 127 } 128