1 /* 2 * Copyright (C) 2017 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 package android.provider; 17 18 import static org.mockito.Matchers.anyInt; 19 import static org.mockito.Matchers.anyString; 20 import static org.mockito.Mockito.mock; 21 import static org.mockito.Mockito.when; 22 23 import static android.provider.FontsContract.Columns.RESULT_CODE_OK; 24 import static android.provider.FontsContract.Columns.RESULT_CODE_FONT_NOT_FOUND; 25 import static android.provider.FontsContract.Columns.RESULT_CODE_FONT_UNAVAILABLE; 26 import static android.provider.FontsContract.Columns.RESULT_CODE_MALFORMED_QUERY; 27 28 import android.content.pm.ApplicationInfo; 29 import android.content.pm.PackageInfo; 30 import android.content.pm.PackageManager.NameNotFoundException; 31 import android.content.pm.PackageManager; 32 import android.content.pm.ProviderInfo; 33 import android.content.pm.Signature; 34 import android.database.MatrixCursor; 35 import android.graphics.fonts.FontVariationAxis; 36 import android.provider.FontsContract.FontInfo; 37 import android.support.test.filters.SmallTest; 38 import android.test.ProviderTestCase2; 39 import android.util.Base64; 40 41 import java.util.ArrayList; 42 import java.util.Arrays; 43 import java.util.List; 44 45 /** 46 * Unit tests for {@link FontsContract}. 47 */ 48 @SmallTest 49 public class FontsContractTest extends ProviderTestCase2<TestFontsProvider> { 50 private static final byte[] BYTE_ARRAY = 51 Base64.decode("e04fd020ea3a6910a2d808002b30", Base64.DEFAULT); 52 // Use a different instance to test byte array comparison 53 private static final byte[] BYTE_ARRAY_COPY = 54 Base64.decode("e04fd020ea3a6910a2d808002b30", Base64.DEFAULT); 55 private static final byte[] BYTE_ARRAY_2 = 56 Base64.decode("e04fd020ea3a6910a2d808002b32", Base64.DEFAULT); 57 private static final String PACKAGE_NAME = "com.my.font.provider.package"; 58 59 private final FontRequest request = new FontRequest( 60 TestFontsProvider.AUTHORITY, PACKAGE_NAME, "query"); 61 private TestFontsProvider mProvider; 62 private PackageManager mPackageManager; 63 64 public FontsContractTest() { 65 super(TestFontsProvider.class, TestFontsProvider.AUTHORITY); 66 } 67 68 public void setUp() throws Exception { 69 super.setUp(); 70 71 mProvider = getProvider(); 72 mPackageManager = mock(PackageManager.class); 73 } 74 75 public void testGetFontFromProvider_resultOK() { 76 FontInfo[] fonts = FontsContract.getFontFromProvider( 77 getMockContext(), request, TestFontsProvider.AUTHORITY, null); 78 assertNotNull(fonts); 79 assertEquals(1, fonts.length); 80 FontInfo font = fonts[0]; 81 assertEquals(TestFontsProvider.TTC_INDEX, font.getTtcIndex()); 82 FontVariationAxis[] actual = font.getAxes(); 83 assertEquals(1, actual.length); 84 assertEquals("wdth", actual[0].getTag()); 85 assertEquals(1.0f, actual[0].getStyleValue(), 0); 86 assertEquals(TestFontsProvider.NORMAL_WEIGHT, font.getWeight()); 87 assertEquals(TestFontsProvider.ITALIC, font.isItalic()); 88 assertNotNull(font.getUri()); 89 assertEquals(RESULT_CODE_OK, font.getResultCode()); 90 } 91 92 public void testGetFontFromProvider_providerDoesntReturnAllFields() { 93 mProvider.setReturnAllFields(false); 94 95 FontInfo[] fonts = FontsContract.getFontFromProvider( 96 getMockContext(), request, TestFontsProvider.AUTHORITY, null); 97 assertNotNull(fonts); 98 assertEquals(1, fonts.length); 99 FontInfo font = fonts[0]; 100 assertEquals(0, font.getTtcIndex()); 101 assertNull(font.getAxes()); 102 assertEquals(400, font.getWeight()); 103 assertFalse(font.isItalic()); 104 assertNotNull(font.getUri()); 105 assertEquals(RESULT_CODE_OK, font.getResultCode()); 106 } 107 108 public void testGetFontFromProvider_resultFontNotFound() { 109 // Make the provider return unknown 110 mProvider.setResultCode(RESULT_CODE_FONT_NOT_FOUND); 111 FontInfo[] fonts = FontsContract.getFontFromProvider( 112 getMockContext(), request, TestFontsProvider.AUTHORITY, null); 113 assertNotNull(fonts); 114 assertEquals(1, fonts.length); 115 FontInfo font = fonts[0]; 116 assertEquals(TestFontsProvider.TTC_INDEX, font.getTtcIndex()); 117 assertNotNull(font.getUri()); 118 assertEquals(RESULT_CODE_FONT_NOT_FOUND, font.getResultCode()); 119 } 120 121 public void testGetFontFromProvider_resultFontUnavailable() { 122 // Make the provider return font unavailable 123 mProvider.setResultCode(RESULT_CODE_FONT_UNAVAILABLE); 124 FontInfo[] fonts = FontsContract.getFontFromProvider( 125 getMockContext(), request, TestFontsProvider.AUTHORITY, null); 126 127 assertNotNull(fonts); 128 assertEquals(1, fonts.length); 129 FontInfo font = fonts[0]; 130 assertEquals(TestFontsProvider.TTC_INDEX, font.getTtcIndex()); 131 FontVariationAxis[] actual = font.getAxes(); 132 assertEquals(1, actual.length); 133 assertEquals("wdth", actual[0].getTag()); 134 assertEquals(1.0f, actual[0].getStyleValue(), 0); 135 assertEquals(TestFontsProvider.NORMAL_WEIGHT, font.getWeight()); 136 assertEquals(TestFontsProvider.ITALIC, font.isItalic()); 137 assertNotNull(font.getUri()); 138 assertEquals(RESULT_CODE_FONT_UNAVAILABLE, font.getResultCode()); 139 } 140 141 public void testGetFontFromProvider_resultMalformedQuery() { 142 // Make the provider return font unavailable 143 mProvider.setResultCode(RESULT_CODE_MALFORMED_QUERY); 144 FontInfo[] fonts = FontsContract.getFontFromProvider( 145 getMockContext(), request, TestFontsProvider.AUTHORITY, null); 146 147 assertNotNull(fonts); 148 assertEquals(1, fonts.length); 149 FontInfo font = fonts[0]; 150 assertEquals(TestFontsProvider.TTC_INDEX, font.getTtcIndex()); 151 FontVariationAxis[] actual = font.getAxes(); 152 assertEquals(1, actual.length); 153 assertEquals("wdth", actual[0].getTag()); 154 assertEquals(1.0f, actual[0].getStyleValue(), 0); 155 assertEquals(TestFontsProvider.NORMAL_WEIGHT, font.getWeight()); 156 assertEquals(TestFontsProvider.ITALIC, font.isItalic()); 157 assertNotNull(font.getUri()); 158 assertEquals(RESULT_CODE_MALFORMED_QUERY, font.getResultCode()); 159 } 160 161 public void testGetFontFromProvider_resultFontNotFoundSecondRow() { 162 MatrixCursor cursor = new MatrixCursor(new String[] { FontsContract.Columns._ID, 163 FontsContract.Columns.TTC_INDEX, FontsContract.Columns.VARIATION_SETTINGS, 164 FontsContract.Columns.WEIGHT, FontsContract.Columns.ITALIC, 165 FontsContract.Columns.RESULT_CODE }); 166 cursor.addRow(new Object[] { 1, 0, null, 400, 0, RESULT_CODE_OK}); 167 cursor.addRow(new Object[] { 1, 0, null, 400, 0, 168 RESULT_CODE_FONT_NOT_FOUND}); 169 mProvider.setCustomCursor(cursor); 170 FontInfo[] fonts = FontsContract.getFontFromProvider( 171 getMockContext(), request, TestFontsProvider.AUTHORITY, null); 172 173 assertNotNull(fonts); 174 assertEquals(2, fonts.length); 175 176 FontInfo font = fonts[0]; 177 assertEquals(0, font.getTtcIndex()); 178 assertNull(font.getAxes()); 179 assertEquals(400, font.getWeight()); 180 assertFalse(font.isItalic()); 181 assertNotNull(font.getUri()); 182 assertEquals(RESULT_CODE_OK, font.getResultCode()); 183 184 font = fonts[1]; 185 assertEquals(0, font.getTtcIndex()); 186 assertNull(font.getAxes()); 187 assertEquals(400, font.getWeight()); 188 assertFalse(font.isItalic()); 189 assertNotNull(font.getUri()); 190 assertEquals(RESULT_CODE_FONT_NOT_FOUND, font.getResultCode()); 191 } 192 193 public void testGetFontFromProvider_resultFontNotFoundOtherRow() { 194 MatrixCursor cursor = new MatrixCursor(new String[] { FontsContract.Columns._ID, 195 FontsContract.Columns.TTC_INDEX, FontsContract.Columns.VARIATION_SETTINGS, 196 FontsContract.Columns.WEIGHT, FontsContract.Columns.ITALIC, 197 FontsContract.Columns.RESULT_CODE }); 198 cursor.addRow(new Object[] { 1, 0, null, 400, 0, RESULT_CODE_OK}); 199 cursor.addRow(new Object[] { 1, 0, null, 400, 0, 200 RESULT_CODE_FONT_NOT_FOUND}); 201 cursor.addRow(new Object[] { 1, 0, null, 400, 0, RESULT_CODE_OK}); 202 mProvider.setCustomCursor(cursor); 203 FontInfo[] fonts = FontsContract.getFontFromProvider( 204 getMockContext(), request, TestFontsProvider.AUTHORITY, null); 205 206 assertNotNull(fonts); 207 assertEquals(3, fonts.length); 208 209 FontInfo font = fonts[0]; 210 assertEquals(0, font.getTtcIndex()); 211 assertNull(font.getAxes()); 212 assertEquals(400, font.getWeight()); 213 assertFalse(font.isItalic()); 214 assertNotNull(font.getUri()); 215 assertEquals(RESULT_CODE_OK, font.getResultCode()); 216 217 font = fonts[1]; 218 assertEquals(0, font.getTtcIndex()); 219 assertNull(font.getAxes()); 220 assertEquals(400, font.getWeight()); 221 assertFalse(font.isItalic()); 222 assertNotNull(font.getUri()); 223 assertEquals(RESULT_CODE_FONT_NOT_FOUND, font.getResultCode()); 224 225 font = fonts[2]; 226 assertEquals(0, font.getTtcIndex()); 227 assertNull(font.getAxes()); 228 assertEquals(400, font.getWeight()); 229 assertFalse(font.isItalic()); 230 assertNotNull(font.getUri()); 231 assertEquals(RESULT_CODE_OK, font.getResultCode()); 232 } 233 234 public void testGetProvider_providerNotFound() { 235 when(mPackageManager.resolveContentProvider(anyString(), anyInt())).thenReturn(null); 236 237 try { 238 FontsContract.getProvider(mPackageManager, request); 239 fail(); 240 } catch (NameNotFoundException e) { 241 // pass 242 } 243 } 244 245 public void testGetProvider_providerIsSystemApp() throws PackageManager.NameNotFoundException { 246 ProviderInfo info = setupPackageManager(); 247 info.applicationInfo.flags = ApplicationInfo.FLAG_SYSTEM; 248 when(mPackageManager.resolveContentProvider(anyString(), anyInt())).thenReturn(info); 249 250 ProviderInfo result = FontsContract.getProvider(mPackageManager, request); 251 assertEquals(info, result); 252 } 253 254 public void testGetProvider_providerIsSystemAppWrongPackage() 255 throws PackageManager.NameNotFoundException { 256 ProviderInfo info = setupPackageManager(); 257 info.applicationInfo.flags = ApplicationInfo.FLAG_SYSTEM; 258 when(mPackageManager.resolveContentProvider(anyString(), anyInt())).thenReturn(info); 259 260 try { 261 FontsContract.getProvider( 262 mPackageManager, 263 new FontRequest(TestFontsProvider.AUTHORITY, "com.wrong.package", "query")); 264 fail(); 265 } catch (NameNotFoundException e) { 266 // pass 267 } 268 269 } 270 271 public void testGetProvider_providerIsNonSystemAppNoCerts() 272 throws PackageManager.NameNotFoundException { 273 setupPackageManager(); 274 275 assertNull(FontsContract.getProvider(mPackageManager, request)); 276 } 277 278 public void testGetProvider_providerIsNonSystemAppWrongCerts() 279 throws PackageManager.NameNotFoundException { 280 setupPackageManager(); 281 282 byte[] wrongCert = Base64.decode("this is a wrong cert", Base64.DEFAULT); 283 List<byte[]> certList = Arrays.asList(wrongCert); 284 FontRequest requestWrongCerts = new FontRequest( 285 TestFontsProvider.AUTHORITY, PACKAGE_NAME, "query", Arrays.asList(certList)); 286 287 assertNull(FontsContract.getProvider(mPackageManager, requestWrongCerts)); 288 } 289 290 public void testGetProvider_providerIsNonSystemAppCorrectCerts() 291 throws PackageManager.NameNotFoundException { 292 ProviderInfo info = setupPackageManager(); 293 294 List<byte[]> certList = Arrays.asList(BYTE_ARRAY); 295 FontRequest requestRightCerts = new FontRequest( 296 TestFontsProvider.AUTHORITY, PACKAGE_NAME, "query", Arrays.asList(certList)); 297 ProviderInfo result = FontsContract.getProvider( 298 mPackageManager, requestRightCerts); 299 300 assertEquals(info, result); 301 } 302 303 public void testGetProvider_providerIsNonSystemAppMoreCerts() 304 throws PackageManager.NameNotFoundException { 305 setupPackageManager(); 306 307 byte[] wrongCert = Base64.decode("this is a wrong cert", Base64.DEFAULT); 308 List<byte[]> certList = Arrays.asList(wrongCert, BYTE_ARRAY); 309 FontRequest requestRightCerts = new FontRequest( 310 TestFontsProvider.AUTHORITY, PACKAGE_NAME, "query", Arrays.asList(certList)); 311 assertNull(FontsContract.getProvider(mPackageManager, requestRightCerts)); 312 } 313 314 public void testGetProvider_providerIsNonSystemAppDuplicateCerts() 315 throws PackageManager.NameNotFoundException { 316 ProviderInfo info = new ProviderInfo(); 317 info.packageName = PACKAGE_NAME; 318 info.applicationInfo = new ApplicationInfo(); 319 when(mPackageManager.resolveContentProvider(anyString(), anyInt())).thenReturn(info); 320 PackageInfo packageInfo = new PackageInfo(); 321 Signature signature = mock(Signature.class); 322 when(signature.toByteArray()).thenReturn(BYTE_ARRAY_COPY); 323 Signature signature2 = mock(Signature.class); 324 when(signature2.toByteArray()).thenReturn(BYTE_ARRAY_COPY); 325 packageInfo.packageName = PACKAGE_NAME; 326 packageInfo.signatures = new Signature[] { signature, signature2 }; 327 when(mPackageManager.getPackageInfo(anyString(), anyInt())).thenReturn(packageInfo); 328 329 // The provider has {BYTE_ARRAY_COPY, BYTE_ARRAY_COPY}, the request has 330 // {BYTE_ARRAY_2, BYTE_ARRAY_COPY}. 331 List<byte[]> certList = Arrays.asList(BYTE_ARRAY_2, BYTE_ARRAY_COPY); 332 FontRequest requestRightCerts = new FontRequest( 333 TestFontsProvider.AUTHORITY, PACKAGE_NAME, "query", Arrays.asList(certList)); 334 assertNull(FontsContract.getProvider(mPackageManager, requestRightCerts)); 335 } 336 337 public void testGetProvider_providerIsNonSystemAppCorrectCertsSeveralSets() 338 throws PackageManager.NameNotFoundException { 339 ProviderInfo info = setupPackageManager(); 340 341 List<List<byte[]>> certList = new ArrayList<>(); 342 byte[] wrongCert = Base64.decode("this is a wrong cert", Base64.DEFAULT); 343 certList.add(Arrays.asList(wrongCert)); 344 certList.add(Arrays.asList(BYTE_ARRAY)); 345 FontRequest requestRightCerts = new FontRequest( 346 TestFontsProvider.AUTHORITY, PACKAGE_NAME, "query", certList); 347 ProviderInfo result = FontsContract.getProvider(mPackageManager, requestRightCerts); 348 349 assertEquals(info, result); 350 } 351 352 public void testGetProvider_providerIsNonSystemAppWrongPackage() 353 throws PackageManager.NameNotFoundException { 354 setupPackageManager(); 355 356 List<List<byte[]>> certList = new ArrayList<>(); 357 certList.add(Arrays.asList(BYTE_ARRAY)); 358 FontRequest requestRightCerts = new FontRequest( 359 TestFontsProvider.AUTHORITY, "com.wrong.package.name", "query", certList); 360 try { 361 FontsContract.getProvider(mPackageManager, requestRightCerts); 362 fail(); 363 } catch (NameNotFoundException e) { 364 // pass 365 } 366 } 367 368 private ProviderInfo setupPackageManager() 369 throws PackageManager.NameNotFoundException { 370 ProviderInfo info = new ProviderInfo(); 371 info.packageName = PACKAGE_NAME; 372 info.applicationInfo = new ApplicationInfo(); 373 when(mPackageManager.resolveContentProvider(anyString(), anyInt())).thenReturn(info); 374 PackageInfo packageInfo = new PackageInfo(); 375 Signature signature = mock(Signature.class); 376 when(signature.toByteArray()).thenReturn(BYTE_ARRAY_COPY); 377 packageInfo.packageName = PACKAGE_NAME; 378 packageInfo.signatures = new Signature[] { signature }; 379 when(mPackageManager.getPackageInfo(anyString(), anyInt())).thenReturn(packageInfo); 380 return info; 381 } 382 } 383