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.contentpreview.payloadtoggle.domain.cursor 18 19 import android.content.ContentInterface 20 import android.content.Intent 21 import android.database.Cursor 22 import android.net.Uri 23 import android.service.chooser.AdditionalContentContract.Columns.URI 24 import androidx.core.os.bundleOf 25 import com.android.intentresolver.contentpreview.payloadtoggle.domain.model.CursorRow 26 import com.android.intentresolver.contentpreview.readSize 27 import com.android.intentresolver.inject.AdditionalContent 28 import com.android.intentresolver.inject.ChooserIntent 29 import com.android.intentresolver.util.cursor.CursorView 30 import com.android.intentresolver.util.cursor.viewBy 31 import com.android.intentresolver.util.withCancellationSignal 32 import dagger.Binds 33 import dagger.Module 34 import dagger.hilt.InstallIn 35 import dagger.hilt.android.components.ViewModelComponent 36 import javax.inject.Inject 37 import javax.inject.Qualifier 38 39 /** [CursorResolver] for the [CursorView] underpinning Shareousel. */ 40 class PayloadToggleCursorResolver 41 @Inject 42 constructor( 43 private val contentResolver: ContentInterface, 44 @AdditionalContent private val cursorUri: Uri, 45 @ChooserIntent private val chooserIntent: Intent, 46 ) : CursorResolver<CursorRow?> { 47 override suspend fun getCursor(): CursorView<CursorRow?>? = withCancellationSignal { signal -> 48 runCatching { 49 contentResolver.query( 50 cursorUri, 51 // TODO: uncomment to start using that data 52 arrayOf(URI /*, WIDTH, HEIGHT*/), 53 bundleOf(Intent.EXTRA_INTENT to chooserIntent), 54 signal, 55 ) 56 } 57 .getOrNull() 58 ?.viewBy { readUri()?.let { uri -> CursorRow(uri, readSize(), position) } } 59 } 60 61 private fun Cursor.readUri(): Uri? { 62 val uriIdx = columnNames.indexOf(URI) 63 if (uriIdx < 0) return null 64 return runCatching { 65 getString(uriIdx)?.let(Uri::parse)?.takeIf { it.authority != cursorUri.authority } 66 } 67 .getOrNull() 68 } 69 70 @Module 71 @InstallIn(ViewModelComponent::class) 72 interface Binding { 73 @Binds 74 @PayloadToggle 75 fun bind(cursorResolver: PayloadToggleCursorResolver): CursorResolver<CursorRow?> 76 } 77 } 78 79 /** [CursorResolver] for the [CursorView] underpinning Shareousel. */ 80 @Qualifier @MustBeDocumented @Retention(AnnotationRetention.RUNTIME) annotation class PayloadToggle 81