blob: 9dcce1e51e0b4b8b98154c635928937494c867c7 [file] [log] [blame]
Johannes Carlsson872a52c2010-12-20 16:14:52 +01001/*
2 * Copyright (C) 2010 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 */
Jeff Sharkey4e5efa32018-10-04 19:21:53 -060016
Johannes Carlsson872a52c2010-12-20 16:14:52 +010017package android.content;
18
Jeff Sharkey4e5efa32018-10-04 19:21:53 -060019import static org.junit.Assert.assertEquals;
20import static org.junit.Assert.assertTrue;
21import static org.mockito.ArgumentMatchers.any;
22import static org.mockito.Mockito.mock;
23import static org.mockito.Mockito.when;
Johannes Carlsson872a52c2010-12-20 16:14:52 +010024
Jeff Sharkey4e5efa32018-10-04 19:21:53 -060025import android.content.res.AssetFileDescriptor;
26import android.graphics.Bitmap;
27import android.graphics.Canvas;
28import android.graphics.Color;
29import android.graphics.ImageDecoder;
30import android.graphics.Paint;
31import android.net.Uri;
32import android.os.MemoryFile;
33import android.os.ParcelFileDescriptor;
Jeff Sharkey4e5efa32018-10-04 19:21:53 -060034import android.util.Size;
Johannes Carlsson872a52c2010-12-20 16:14:52 +010035
Tadashi G. Takaokab4470f22019-01-15 18:29:15 +090036import androidx.test.InstrumentationRegistry;
37import androidx.test.runner.AndroidJUnit4;
38
Jeff Sharkey4e5efa32018-10-04 19:21:53 -060039import org.junit.After;
40import org.junit.Before;
41import org.junit.Test;
42import org.junit.runner.RunWith;
43
44@RunWith(AndroidJUnit4.class)
45public class ContentResolverTest {
46
47 private ContentResolver mResolver;
48 private IContentProvider mProvider;
49 private ContentProviderClient mClient;
50
51 private int mSize = 256_000;
52 private MemoryFile mImage;
53
54 @Before
55 public void setUp() throws Exception {
56 mResolver = InstrumentationRegistry.getInstrumentation().getTargetContext()
57 .getContentResolver();
58 mProvider = mock(IContentProvider.class);
59 mClient = new ContentProviderClient(mResolver, mProvider, false);
60
61 mImage = new MemoryFile("temp.png", mSize);
Johannes Carlsson872a52c2010-12-20 16:14:52 +010062 }
63
Jeff Sharkey4e5efa32018-10-04 19:21:53 -060064 @After
65 public void tearDown() throws Exception {
66 mImage.close();
67 mImage = null;
68 }
69
70 private void initImage(int width, int height) throws Exception {
71 final Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
72 final Canvas canvas = new Canvas(bitmap);
73
74 canvas.drawColor(Color.RED);
75
76 final Paint paint = new Paint();
77 paint.setColor(Color.BLUE);
78 paint.setStyle(Paint.Style.FILL);
79 canvas.drawRect(0, 0, width / 2, height / 2, paint);
80
81 bitmap.compress(Bitmap.CompressFormat.PNG, 90, mImage.getOutputStream());
82
83 final AssetFileDescriptor afd = new AssetFileDescriptor(
84 new ParcelFileDescriptor(mImage.getFileDescriptor()), 0, mSize, null);
Philip P. Moltmann128b7032019-09-27 08:44:12 -070085 when(mProvider.openTypedAssetFile(any(), any(), any(), any(), any(), any())).thenReturn(
86 afd);
Jeff Sharkey4e5efa32018-10-04 19:21:53 -060087 }
88
Tony Huangde421372019-10-25 18:15:24 +080089 private static void assertImageAspectAndContents(int width, int height, Bitmap bitmap) {
Jeff Sharkey4e5efa32018-10-04 19:21:53 -060090 // And correct aspect ratio
Tony Huangde421372019-10-25 18:15:24 +080091 final int before = (100 * width) / height;
Jeff Sharkey4e5efa32018-10-04 19:21:53 -060092 final int after = (100 * bitmap.getWidth()) / bitmap.getHeight();
93 assertEquals(before, after);
94
95 // And scaled correctly
96 final int halfX = bitmap.getWidth() / 2;
97 final int halfY = bitmap.getHeight() / 2;
Tony Huangde421372019-10-25 18:15:24 +080098 assertEquals(Color.BLUE, bitmap.getPixel(halfX - 5, halfY - 5));
99 assertEquals(Color.RED, bitmap.getPixel(halfX + 5, halfY - 5));
100 assertEquals(Color.RED, bitmap.getPixel(halfX - 5, halfY + 5));
101 assertEquals(Color.RED, bitmap.getPixel(halfX + 5, halfY + 5));
Jeff Sharkey4e5efa32018-10-04 19:21:53 -0600102 }
103
104 @Test
105 public void testLoadThumbnail_Normal() throws Exception {
106 initImage(1280, 960);
107
108 Bitmap res = ContentResolver.loadThumbnail(mClient,
109 Uri.parse("content://com.example/"), new Size(1280, 960), null,
110 ImageDecoder.ALLOCATOR_SOFTWARE);
111
112 // Size should be untouched
113 assertEquals(1280, res.getWidth());
114 assertEquals(960, res.getHeight());
115
Tony Huangde421372019-10-25 18:15:24 +0800116 assertImageAspectAndContents(1280, 960, res);
Jeff Sharkey4e5efa32018-10-04 19:21:53 -0600117 }
118
119 @Test
120 public void testLoadThumbnail_Scaling() throws Exception {
121 initImage(1280, 960);
122
123 Bitmap res = ContentResolver.loadThumbnail(mClient,
124 Uri.parse("content://com.example/"), new Size(320, 240), null,
125 ImageDecoder.ALLOCATOR_SOFTWARE);
126
127 // Size should be much smaller
128 assertTrue(res.getWidth() <= 640);
129 assertTrue(res.getHeight() <= 480);
130
Tony Huangde421372019-10-25 18:15:24 +0800131 assertImageAspectAndContents(1280, 960, res);
Jeff Sharkey4e5efa32018-10-04 19:21:53 -0600132 }
133
134 @Test
135 public void testLoadThumbnail_Aspect() throws Exception {
136 initImage(1280, 960);
137
138 Bitmap res = ContentResolver.loadThumbnail(mClient,
139 Uri.parse("content://com.example/"), new Size(240, 320), null,
140 ImageDecoder.ALLOCATOR_SOFTWARE);
141
142 // Size should be much smaller
143 assertTrue(res.getWidth() <= 640);
144 assertTrue(res.getHeight() <= 480);
145
Tony Huangde421372019-10-25 18:15:24 +0800146 assertImageAspectAndContents(1280, 960, res);
Jeff Sharkey4e5efa32018-10-04 19:21:53 -0600147 }
148
149 @Test
150 public void testLoadThumbnail_Tiny() throws Exception {
151 initImage(32, 24);
152
153 Bitmap res = ContentResolver.loadThumbnail(mClient,
154 Uri.parse("content://com.example/"), new Size(320, 240), null,
155 ImageDecoder.ALLOCATOR_SOFTWARE);
156
157 // Size should be untouched
158 assertEquals(32, res.getWidth());
159 assertEquals(24, res.getHeight());
160
Tony Huangde421372019-10-25 18:15:24 +0800161 assertImageAspectAndContents(32, 24, res);
162 }
163
164 @Test
165 public void testLoadThumbnail_Large() throws Exception {
166 // Test very large and extreme ratio image
167 initImage(1080, 30000);
168
169 Bitmap res = ContentResolver.loadThumbnail(mClient,
170 Uri.parse("content://com.example/"), new Size(1080, 540), null,
171 ImageDecoder.ALLOCATOR_SOFTWARE);
172
173 // Size should be much smaller
174 assertTrue(res.getWidth() <= 2160);
175 assertTrue(res.getHeight() <= 1080);
176
177 assertImageAspectAndContents(1080, 30000, res);
Johannes Carlsson872a52c2010-12-20 16:14:52 +0100178 }
Jeff Sharkeybc2ae002018-07-31 10:45:37 -0600179
180 @Test
181 public void testTranslateDeprecatedDataPath() throws Exception {
182 assertTranslate(Uri.parse("content://com.example/path/?foo=bar&baz=meow"));
183 assertTranslate(Uri.parse("content://com.example/path/subpath/12/"));
184 assertTranslate(Uri.parse("content://com.example/path/subpath/12"));
185 assertTranslate(Uri.parse("content://com.example/path/12"));
186 assertTranslate(Uri.parse("content://com.example/"));
187 assertTranslate(Uri.parse("content://com.example"));
188 }
189
190 private static void assertTranslate(Uri uri) {
191 assertEquals(uri, ContentResolver
192 .translateDeprecatedDataPath(ContentResolver.translateDeprecatedDataPath(uri)));
193 }
Dmitri Plotnikovd55a3872020-01-16 17:00:02 -0800194
195 @Test
196 public void testGetType_localProvider() {
197 // This provider is running in the same process as the test and is already registered with
198 // the ContentResolver when the application starts, see
199 // ActivityThread#installContentProviders. This allows ContentResolver to follow a
200 // streamlined code path.
201 String type = mResolver.getType(Uri.parse("content://android.content.FakeProviderLocal"));
202 assertEquals("fake/local", type);
203 }
204
205 @Test
206 public void testGetType_remoteProvider() {
207 // This provider is running in a different process, which will need to be started
208 // in order to acquire the provider
209 String type = mResolver.getType(Uri.parse("content://android.content.FakeProviderRemote"));
210 assertEquals("fake/remote", type);
211 }
Johannes Carlsson872a52c2010-12-20 16:14:52 +0100212}