1 /*
<lambda>null2  * 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.avatarpicker.ui.details.items.media
18 
19 import android.graphics.ImageDecoder
20 import android.multiuser.Flags
21 import android.net.Uri
22 import android.util.TypedValue
23 import androidx.activity.compose.rememberLauncherForActivityResult
24 import androidx.activity.result.PickVisualMediaRequest
25 import androidx.activity.result.contract.ActivityResultContracts
26 import androidx.compose.runtime.Composable
27 import androidx.compose.ui.platform.LocalContext
28 import com.android.avatarpicker.domain.getCropIntent
29 import com.android.avatarpicker.domain.saveBitmap
30 import com.android.avatarpicker.ui.ResultHandler
31 import com.android.avatarpicker.ui.details.items.ResourceViewModel
32 import com.android.avatarpicker.ui.details.items.UriTypedItem
33 import java.io.IOException
34 
35 @Composable
36 fun PhotoPickerIcon(
37     viewModel: ResourceViewModel, resultHandler: ResultHandler
38 ) {
39 
40     val cropResult = rememberLauncherForCropActivity { uri ->
41         uri?.let {
42             resultHandler.onSelect(UriTypedItem(viewModel.typeId, it))
43         } ?: resultHandler.unselect()
44     }
45 
46     val tempFile = resultHandler.getTempFile()
47     val contentUri: Uri = resultHandler.getContentUri()
48     val contentResolver = LocalContext.current.contentResolver
49     val avatarSizeInPixels = TypedValue.applyDimension(
50         TypedValue.COMPLEX_UNIT_DIP, 190f, LocalContext.current.resources.displayMetrics
51     ).toInt()
52 
53     val photoPickerLauncher =
54         rememberLauncherForActivityResult(ActivityResultContracts.PickVisualMedia()) { result ->
55             result?.let { selectedUri ->
56                 if(Flags.fixAvatarPickerNotRespondingForNewUser()){
57                     try {
58                             contentResolver.openInputStream(selectedUri)?.use { inputStream ->
59                                 contentResolver.openOutputStream(contentUri)?.use { outputStream ->
60                                     inputStream.copyTo(outputStream)
61                                     val cropIntent = getCropIntent(contentUri, avatarSizeInPixels)
62                                     cropResult.launch(cropIntent)
63                                 } ?: resultHandler.unselect()
64                             } ?: resultHandler.unselect()
65                         } catch (e: Exception) {
66                             resultHandler.onError(e)
67                         }
68                 } else {
69                     val source = ImageDecoder.createSource(contentResolver, selectedUri)
70                     ImageDecoder.decodeBitmap(source).let { bitmap ->
71                         try {
72                             tempFile.saveBitmap(bitmap)
73                             val cropIntent = getCropIntent(contentUri, avatarSizeInPixels)
74                             cropResult.launch(cropIntent)
75                         } catch (exc: IOException) {
76                             resultHandler.onError(exc)
77                         }
78                     }
79                 }
80             } ?: resultHandler.unselect()
81         }
82     MediaIcon(viewModel) {
83         resultHandler.onLoading()
84         photoPickerLauncher.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly))
85     }
86 }