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 androidx.compose.foundation.text.input.internal
18 
19 import android.content.ClipData
20 import android.net.Uri
21 import android.os.Build
22 import android.os.Parcel
23 import android.view.DragEvent
24 import androidx.compose.foundation.content.createClipData
25 import androidx.compose.ui.geometry.Offset
26 
27 /**
28  * Helper utilities for creating drag events.
29  *
30  * This class is a copy-paste from DragAndDrop artifact with the addition of configurable offset.
31  * Also it does not mock but uses Parcel to create a DragEvent.
32  */
33 object DragAndDropTestUtils {
34     private const val SAMPLE_TEXT = "Drag Text"
35     private val SAMPLE_URI = Uri.parse("http://www.google.com")
36 
37     /**
38      * Makes a stub drag event containing fake text data.
39      *
40      * @param action One of the [DragEvent] actions.
41      */
makeTextDragEventnull42     fun makeTextDragEvent(
43         action: Int,
44         text: String = SAMPLE_TEXT,
45         offset: Offset = Offset.Zero,
46     ): DragEvent {
47         return makeDragEvent(
48             action = action,
49             clipData = createClipData { addText(text) },
50             offset = offset
51         )
52     }
53 
54     /**
55      * Makes a stub drag event containing an image mimetype and fake uri.
56      *
57      * @param action One of the [DragEvent] actions.
58      */
makeImageDragEventnull59     fun makeImageDragEvent(
60         action: Int,
61         item: Uri = SAMPLE_URI,
62         offset: Offset = Offset.Zero,
63     ): DragEvent {
64         return makeDragEvent(
65             action = action,
66             clipData =
67                 createClipData {
68                     // We're not actually resolving Uris in these tests, so this can be anything:
69                     addUri(item, mimeType = "image/png")
70                 },
71             offset = offset
72         )
73     }
74 
makeDragEventnull75     fun makeDragEvent(action: Int, clipData: ClipData, offset: Offset = Offset.Zero): DragEvent {
76         val parcel = Parcel.obtain()
77 
78         parcel.writeInt(action)
79         parcel.writeFloat(offset.x)
80         parcel.writeFloat(offset.y)
81         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
82             // mOffset was made part of DragEvent in API 31.
83             parcel.writeFloat(0f)
84             parcel.writeFloat(0f)
85         }
86         if (Build.VERSION.SDK_INT >= 35) {
87             // mFlags was added
88             parcel.writeInt(0)
89         }
90         parcel.writeInt(0) // Result
91         parcel.writeInt(1)
92         clipData.writeToParcel(parcel, 0)
93         parcel.writeInt(1)
94         clipData.description.writeToParcel(parcel, 0)
95 
96         parcel.setDataPosition(0)
97         return DragEvent.CREATOR.createFromParcel(parcel)
98     }
99 }
100