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.tests.utils
18 
19 import android.content.ContentProvider
20 import android.content.ContentValues
21 import android.database.Cursor
22 import android.net.Uri
23 import com.android.photopicker.data.model.Media
24 import com.android.photopicker.data.model.MediaSource
25 import java.time.LocalDateTime
26 import java.time.ZoneOffset
27 import java.time.temporal.ChronoUnit
28 
29 /*
30  * Define an implementation of ContentProvider that stubs out all methods
31  */
32 class StubProvider : ContentProvider() {
33 
34     companion object {
35         val AUTHORITY = "stubprovider"
36 
37         /**
38          * Return a list of stubbed [Media] that match the AUTHORITY string of this provider. Each
39          * Media item returned will be unique.
40          *
41          * @param count The number of media to generate and return.
42          * @return
43          */
getTestMediaFromStubProvidernull44         fun getTestMediaFromStubProvider(count: Int): List<Media> {
45 
46             val currentDateTime = LocalDateTime.now()
47             return buildList<Media>() {
48                 for (i in 1..count) {
49                     add(
50                         Media.Image(
51                             mediaId = "$i",
52                             pickerId = i.toLong(),
53                             authority = AUTHORITY,
54                             mediaSource = MediaSource.LOCAL,
55                             mediaUri =
56                                 Uri.EMPTY.buildUpon()
57                                     .apply {
58                                         scheme("content")
59                                         authority(AUTHORITY)
60                                         path("$i")
61                                     }
62                                     .build(),
63                             glideLoadableUri =
64                                 Uri.EMPTY.buildUpon()
65                                     .apply {
66                                         scheme("content")
67                                         authority(AUTHORITY)
68                                         path("$i")
69                                     }
70                                     .build(),
71                             dateTakenMillisLong =
72                                 currentDateTime
73                                     .minus(i.toLong(), ChronoUnit.DAYS)
74                                     .toEpochSecond(ZoneOffset.UTC) * 1000,
75                             sizeInBytes = 1000L,
76                             mimeType = "image/png",
77                             standardMimeTypeExtension = 1,
78                         )
79                     )
80                 }
81             }
82         }
83     }
84     /*
85      * Always return true, indicating that the
86      * provider loaded correctly.
87      */
onCreatenull88     override fun onCreate(): Boolean = true
89 
90     /*
91      * Return no type for MIME type
92      */
93     override fun getType(uri: Uri): String? = null
94 
95     /*
96      * query() always returns no results
97      *
98      */
99     override fun query(
100         uri: Uri,
101         projection: Array<String>?,
102         selection: String?,
103         selectionArgs: Array<String>?,
104         sortOrder: String?
105     ): Cursor? = null
106 
107     /*
108      * insert() always returns null (no URI)
109      */
110     override fun insert(uri: Uri, values: ContentValues?): Uri? = null
111 
112     /*
113      * delete() always returns "no rows affected" (0)
114      */
115     override fun delete(uri: Uri, selection: String?, selectionArgs: Array<String>?): Int = 0
116 
117     /*
118      * update() always returns "no rows affected" (0)
119      */
120     override fun update(
121         uri: Uri,
122         values: ContentValues?,
123         selection: String?,
124         selectionArgs: Array<String>?
125     ): Int = 0
126 }
127