1 /* 2 * Copyright (C) 2023 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 18 19 import android.app.Application 20 import android.content.ContentResolver 21 import android.content.Intent 22 import android.net.Uri 23 import androidx.annotation.MainThread 24 import androidx.lifecycle.ViewModel 25 import androidx.lifecycle.ViewModelProvider 26 import androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory.Companion.APPLICATION_KEY 27 import androidx.lifecycle.viewModelScope 28 import androidx.lifecycle.viewmodel.CreationExtras 29 import com.android.intentresolver.R 30 import com.android.intentresolver.inject.Background 31 import kotlinx.coroutines.CoroutineDispatcher 32 import kotlinx.coroutines.Dispatchers 33 import kotlinx.coroutines.plus 34 35 /** A view model for the preview logic */ 36 class PreviewViewModel( 37 private val contentResolver: ContentResolver, 38 // TODO: inject ImageLoader instead 39 private val thumbnailSize: Int, 40 @Background private val dispatcher: CoroutineDispatcher = Dispatchers.IO, 41 ) : BasePreviewViewModel() { 42 private var targetIntent: Intent? = null 43 private var additionalContentUri: Uri? = null 44 private var isPayloadTogglingEnabled = false 45 <lambda>null46 override val previewDataProvider by lazy { 47 val targetIntent = requireNotNull(this.targetIntent) { "Not initialized" } 48 PreviewDataProvider( 49 viewModelScope + dispatcher, 50 targetIntent, 51 additionalContentUri, 52 contentResolver, 53 isPayloadTogglingEnabled, 54 ) 55 } 56 <lambda>null57 override val imageLoader by lazy { 58 ImagePreviewImageLoader( 59 viewModelScope + dispatcher, 60 thumbnailSize, 61 contentResolver, 62 cacheSize = 16 63 ) 64 } 65 66 // TODO: make the view model injectable and inject these dependencies instead 67 @MainThread initnull68 override fun init( 69 targetIntent: Intent, 70 additionalContentUri: Uri?, 71 isPayloadTogglingEnabled: Boolean, 72 ) { 73 if (this.targetIntent != null) return 74 this.targetIntent = targetIntent 75 this.additionalContentUri = additionalContentUri 76 this.isPayloadTogglingEnabled = isPayloadTogglingEnabled 77 } 78 79 companion object { 80 val Factory: ViewModelProvider.Factory = 81 object : ViewModelProvider.Factory { 82 @Suppress("UNCHECKED_CAST") createnull83 override fun <T : ViewModel> create( 84 modelClass: Class<T>, 85 extras: CreationExtras 86 ): T { 87 val application: Application = checkNotNull(extras[APPLICATION_KEY]) 88 return PreviewViewModel( 89 application.contentResolver, 90 application.resources.getDimensionPixelSize( 91 R.dimen.chooser_preview_image_max_dimen 92 ) 93 ) 94 as T 95 } 96 } 97 } 98 } 99