1 /*
2  * Copyright 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.photopicker.core.configuration
18 
19 import android.content.Intent
20 import com.android.photopicker.core.events.generatePickerSessionId
21 import kotlinx.coroutines.CoroutineScope
22 import kotlinx.coroutines.flow.SharingStarted
23 import kotlinx.coroutines.flow.StateFlow
24 import kotlinx.coroutines.flow.flow
25 import kotlinx.coroutines.flow.stateIn
26 
27 /**
28  * Helper function to generate a [StateFlow] that mimics the flow emitted by the
29  * [ConfigurationManager]. This flow immediately emits the provided [PhotopickerConfiguration] or a
30  * default test configuration if none is provided.
31  */
provideTestConfigurationFlownull32 fun provideTestConfigurationFlow(
33     scope: CoroutineScope,
34     defaultConfiguration: PhotopickerConfiguration = TestPhotopickerConfiguration.default(),
35 ): StateFlow<PhotopickerConfiguration> {
36 
37     return flow { emit(defaultConfiguration) }
38         .stateIn(scope, SharingStarted.Eagerly, initialValue = defaultConfiguration)
39 }
40 
41 /** Builder for a [PhotopickerConfiguration] to use in Tests. */
42 class TestPhotopickerConfiguration {
43     companion object {
44         /**
45          * Create a new [PhotopickerConfiguration]
46          *
47          * @return [PhotopickerConfiguration] with the applied properties.
48          */
buildnull49         inline fun build(block: Builder.() -> Unit) = Builder().apply(block).build()
50 
51         /**
52          * Create a new [PhotopickerConfiguration].
53          *
54          * @return [PhotopickerConfiguration] with default properties.
55          */
56         fun default() = Builder().build()
57     }
58 
59     /** Internal Builder implementation. Callers should use [TestPhotopickerConfiguration.build]. */
60     class Builder {
61         private var action: String = ""
62         private var intent: Intent? = null
63         private var selectionLimit: Int = DEFAULT_SELECTION_LIMIT
64         private var pickImagesInOrder: Boolean = false
65         private var callingPackage: String? = null
66         private var callingPackageUid: Int? = null
67         private var callingPackageLabel: String? = null
68         private var runtimeEnv: PhotopickerRuntimeEnv = PhotopickerRuntimeEnv.ACTIVITY
69         private var sessionId: Int = generatePickerSessionId()
70         private var flags: PhotopickerFlags = PhotopickerFlags()
71         private var mimeTypes: ArrayList<String> = arrayListOf("image/*", "video/*")
72 
73         fun action(value: String) = apply { this.action = value }
74 
75         fun intent(value: Intent?) = apply { this.intent = value }
76 
77         fun selectionLimit(value: Int) = apply { this.selectionLimit = value }
78 
79         fun pickImagesInOrder(value: Boolean) = apply { this.pickImagesInOrder = value }
80 
81         fun callingPackage(value: String) = apply { this.callingPackage = value }
82 
83         fun callingPackageUid(value: Int) = apply { this.callingPackageUid = value }
84 
85         fun callingPackageLabel(value: String) = apply { this.callingPackageLabel = value }
86 
87         fun runtimeEnv(value: PhotopickerRuntimeEnv) = apply { this.runtimeEnv = value }
88 
89         fun sessionId(value: Int) = apply { this.sessionId = value }
90 
91         fun flags(value: PhotopickerFlags) = apply { this.flags = value }
92 
93         fun mimeTypes(value: ArrayList<String>) = apply { this.mimeTypes = value }
94 
95         fun build(): PhotopickerConfiguration {
96             return PhotopickerConfiguration(
97                 action = action,
98                 intent = intent,
99                 selectionLimit = selectionLimit,
100                 pickImagesInOrder = pickImagesInOrder,
101                 callingPackage = callingPackage,
102                 callingPackageUid = callingPackageUid,
103                 callingPackageLabel = callingPackageLabel,
104                 runtimeEnv = runtimeEnv,
105                 sessionId = sessionId,
106                 flags = flags,
107                 mimeTypes = mimeTypes,
108             )
109         }
110     }
111 }
112