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.providers.media.util;
18 
19 import android.content.ContentResolver;
20 import android.content.ContentUris;
21 import android.content.Context;
22 import android.net.Uri;
23 import android.os.Environment;
24 import android.os.UserHandle;
25 import android.provider.MediaStore;
26 
27 import androidx.test.platform.app.InstrumentationRegistry;
28 
29 import com.android.providers.media.photopicker.PickerSyncController;
30 
31 import java.io.File;
32 import java.io.FileOutputStream;
33 import java.io.IOException;
34 import java.io.InputStream;
35 import java.io.OutputStream;
36 
37 /**
38  * A utility class to assist creating files for tests
39  */
40 public class FileCreationUtils {
41 
42     /**
43      * Helper method to insert a test image/png into given {@code contentResolver}
44      *
45      * @param contentResolver ContentResolver to which file is inserted
46      * @param name            file name
47      * @return {@link Long} the files table {@link MediaStore.MediaColumns.ID}
48      */
insertFileInResolver(ContentResolver contentResolver, String name)49     public static Long insertFileInResolver(ContentResolver contentResolver, String name)
50             throws IOException {
51         return insertFileInResolver(contentResolver, name, "png");
52     }
53 
54     /**
55      * Helper method to insert a test item into given {@code contentResolver} with the provided
56      * mimeType.
57      *
58      * @param contentResolver ContentResolver to which file is inserted
59      * @param name            file name
60      * @return {@link Long} the files table {@link MediaStore.MediaColumns.ID}
61      */
insertFileInResolver(ContentResolver contentResolver, String name, String mimeType)62     public static Long insertFileInResolver(ContentResolver contentResolver, String name,
63             String mimeType)
64             throws IOException {
65         final File dir =
66                 Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
67         final File file = new File(dir, name + System.nanoTime() + "." + mimeType);
68 
69         // Write 1 byte because 0 byte files are not valid in the db
70         try (FileOutputStream fos = new FileOutputStream(file)) {
71             fos.write(1);
72         }
73 
74         Uri uri = MediaStore.scanFile(contentResolver, file);
75         return ContentUris.parseId(uri);
76     }
77 
78     /**
79      * Assembles a valid picker content URI that resembels a content:// uri that would be returned
80      * from photopicker.
81      *
82      * @param id The files table id
83      * @return {@link Uri}
84      */
buildValidPickerUri(Long id)85     public static Uri buildValidPickerUri(Long id) {
86 
87         return initializeUriBuilder(MediaStore.AUTHORITY)
88                 .appendPath("picker")
89                 .appendPath(Integer.toString(UserHandle.myUserId()))
90                 .appendPath(PickerSyncController.LOCAL_PICKER_PROVIDER_AUTHORITY)
91                 .appendPath(MediaStore.AUTHORITY)
92                 .appendPath(Long.toString(id))
93                 .build();
94     }
95 
96     /**
97      * @param authority The authority to encode in the Uri builder.
98      * @return {@link Uri.Builder} for a content:// uri for the passed authority.
99      */
initializeUriBuilder(String authority)100     private static Uri.Builder initializeUriBuilder(String authority) {
101         final Uri.Builder builder = Uri.EMPTY.buildUpon();
102         builder.scheme("content");
103         builder.encodedAuthority(authority);
104 
105         return builder;
106     }
107 
stageMp4File(int resId)108     static File stageMp4File(int resId) throws Exception {
109         final Context context = InstrumentationRegistry.getInstrumentation().getContext();
110         final File file = File.createTempFile("test", ".mp4");
111         try (InputStream in = context.getResources().openRawResource(resId);
112                 OutputStream out = new FileOutputStream(file)) {
113             FileUtils.copy(in, out);
114         }
115         return file;
116     }
117 }
118