TypefaceCompatTest.java revision c357691d3aae8bb2913941267188e12594d5ca80
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
17package android.support.v4.graphics;
18
19import static android.content.res.AssetManager.ACCESS_BUFFER;
20
21import static org.junit.Assert.assertEquals;
22import static org.junit.Assert.assertNotNull;
23import static org.junit.Assert.assertTrue;
24import static org.mockito.Mockito.mock;
25import static org.mockito.Mockito.verify;
26
27import android.graphics.Typeface;
28import android.os.Build;
29import android.os.Bundle;
30import android.os.ParcelFileDescriptor;
31import android.support.test.filters.SmallTest;
32import android.support.test.runner.AndroidJUnit4;
33import android.support.v4.BaseInstrumentationTestCase;
34import android.support.v4.app.TestSupportActivity;
35import android.support.v4.graphics.TypefaceCompat.FontRequestCallback;
36import android.support.v4.graphics.fonts.FontRequest;
37import android.support.v4.graphics.fonts.FontResult;
38import android.support.v4.provider.FontsContractCompat;
39import android.util.Base64;
40
41import org.junit.Before;
42import org.junit.Test;
43import org.junit.runner.RunWith;
44
45import java.io.File;
46import java.io.FileOutputStream;
47import java.io.IOException;
48import java.io.InputStream;
49import java.util.ArrayList;
50import java.util.Arrays;
51import java.util.List;
52
53/**
54 * Tests for {@link TypefaceCompatBaseImpl}.
55 */
56@SmallTest
57@RunWith(AndroidJUnit4.class)
58public class TypefaceCompatTest extends BaseInstrumentationTestCase<TestSupportActivity> {
59    private static final String TEST_FONT_FILE = "fonts/samplefont1.ttf";
60    private static final String CACHE_FILE = "cachedfont.ttf";
61    private static final String PROVIDER = "com.test.fontprovider.authority";
62    private static final String QUERY_CACHED = "query_cached";
63    private static final String QUERY = "query";
64    private static final String PACKAGE = "com.test.fontprovider.package";
65    private static final byte[] BYTE_ARRAY =
66            Base64.decode("e04fd020ea3a6910a2d808002b30", Base64.DEFAULT);
67    private static final List<List<byte[]>> CERTS = Arrays.asList(Arrays.asList(BYTE_ARRAY));
68
69    private TypefaceCompatBaseImpl mCompat;
70
71    public TypefaceCompatTest() {
72        super(TestSupportActivity.class);
73    }
74
75    @Before
76    public void setup() {
77        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
78            mCompat = new TypefaceCompatApi24Impl(mActivityTestRule.getActivity());
79        } else {
80            mCompat = new TypefaceCompatBaseImpl(mActivityTestRule.getActivity());
81        }
82        TypefaceCompatBaseImpl.putInCache(PROVIDER, QUERY_CACHED, Typeface.MONOSPACE);
83    }
84
85    @Test
86    public void testReceiveResult_cachedResult() {
87        FontRequestCallback callback = mock(FontRequestCallback.class);
88
89        mCompat.receiveResult(new FontRequest(PROVIDER, PACKAGE, QUERY_CACHED, CERTS),
90                callback, 0, null);
91
92        verify(callback).onTypefaceRetrieved(Typeface.MONOSPACE);
93    }
94
95    @Test
96    public void testReceiveResult_resultCodeProviderNotFound() {
97        FontRequestCallback callback = mock(FontRequestCallback.class);
98
99        mCompat.receiveResult(new FontRequest(PROVIDER, PACKAGE, QUERY, CERTS), callback,
100                FontsContractCompat.RESULT_CODE_PROVIDER_NOT_FOUND, null);
101
102        verify(callback).onTypefaceRequestFailed(
103                FontRequestCallback.FAIL_REASON_PROVIDER_NOT_FOUND);
104    }
105
106    @Test
107    public void testReceiveResult_resultCodeFontNotFound() {
108        FontRequestCallback callback = mock(FontRequestCallback.class);
109
110        mCompat.receiveResult(new FontRequest(PROVIDER, PACKAGE, QUERY, CERTS), callback,
111                FontsContractCompat.Columns.RESULT_CODE_FONT_NOT_FOUND, null);
112
113        verify(callback).onTypefaceRequestFailed(
114                FontRequestCallback.FAIL_REASON_FONT_NOT_FOUND);
115    }
116
117    @Test
118    public void testReceiveResult_nullBundle() {
119        FontRequestCallback callback = mock(FontRequestCallback.class);
120
121        mCompat.receiveResult(new FontRequest(PROVIDER, PACKAGE, QUERY, CERTS), callback,
122                FontsContractCompat.Columns.RESULT_CODE_OK, null);
123
124        verify(callback).onTypefaceRequestFailed(
125                FontRequestCallback.FAIL_REASON_FONT_NOT_FOUND);
126    }
127
128    @Test
129    public void testReceiveResult_nullResult() {
130        FontRequestCallback callback = mock(FontRequestCallback.class);
131
132        mCompat.receiveResult(new FontRequest(PROVIDER, PACKAGE, QUERY, CERTS), callback,
133                FontsContractCompat.Columns.RESULT_CODE_OK, new Bundle());
134
135        verify(callback).onTypefaceRequestFailed(
136                FontRequestCallback.FAIL_REASON_FONT_NOT_FOUND);
137    }
138
139    @Test
140    public void testReceiveResult_emptyResult() {
141        FontRequestCallback callback = mock(FontRequestCallback.class);
142        Bundle bundle = new Bundle();
143        bundle.putParcelableArrayList(
144                FontsContractCompat.PARCEL_FONT_RESULTS, new ArrayList<FontResult>());
145
146        mCompat.receiveResult(new FontRequest(PROVIDER, PACKAGE, QUERY, CERTS), callback,
147                FontsContractCompat.Columns.RESULT_CODE_OK, bundle);
148
149        verify(callback).onTypefaceRequestFailed(
150                FontRequestCallback.FAIL_REASON_FONT_NOT_FOUND);
151    }
152
153    @Test
154    public void testTypefaceRequestFailureConstantsAreInSync() {
155        // Error codes from the provider are positive numbers and are in sync
156        assertEquals(FontsContractCompat.Columns.RESULT_CODE_FONT_NOT_FOUND,
157                TypefaceCompat.FontRequestCallback.FAIL_REASON_FONT_NOT_FOUND);
158        assertEquals(FontsContractCompat.Columns.RESULT_CODE_FONT_UNAVAILABLE,
159                TypefaceCompat.FontRequestCallback.FAIL_REASON_FONT_UNAVAILABLE);
160        assertEquals(FontsContractCompat.Columns.RESULT_CODE_MALFORMED_QUERY,
161                TypefaceCompat.FontRequestCallback.FAIL_REASON_MALFORMED_QUERY);
162
163        // Internal errors are negative
164        assertTrue(0 > TypefaceCompat.FontRequestCallback.FAIL_REASON_PROVIDER_NOT_FOUND);
165        assertTrue(0 > TypefaceCompat.FontRequestCallback.FAIL_REASON_WRONG_CERTIFICATES);
166        assertTrue(0 > TypefaceCompat.FontRequestCallback.FAIL_REASON_FONT_LOAD_ERROR);
167    }
168
169    private File loadFont() {
170        File cacheFile = new File(mActivityTestRule.getActivity().getCacheDir(), CACHE_FILE);
171        try {
172            copyToCacheFile(TEST_FONT_FILE, cacheFile);
173            return cacheFile;
174        } catch (IOException e) {
175            e.printStackTrace();
176        }
177        return null;
178    }
179
180    private void copyToCacheFile(final String assetPath, final File cacheFile)
181            throws IOException {
182        InputStream is = null;
183        FileOutputStream fos = null;
184        try {
185            is = mActivityTestRule.getActivity().getAssets().open(assetPath, ACCESS_BUFFER);
186            fos = new FileOutputStream(cacheFile, false);
187            byte[] buffer = new byte[1024];
188            int readLen;
189            while ((readLen = is.read(buffer)) != -1) {
190                fos.write(buffer, 0, readLen);
191            }
192        } finally {
193            if (is != null) {
194                is.close();
195            }
196            if (fos != null) {
197                fos.close();
198            }
199        }
200    }
201
202    @Test
203    public void testCreateTypeface() throws IOException, InterruptedException {
204        File file = loadFont();
205        ParcelFileDescriptor pfd =
206                ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
207        try {
208            FontResult result = new FontResult(pfd, 0, null, 400, false /* italic */);
209            Typeface typeface = mCompat.createTypeface(Arrays.asList(result));
210
211            assertNotNull(typeface);
212        } finally {
213            if (file != null) {
214                file.delete();
215            }
216            if (pfd != null) {
217                pfd.close();
218            }
219        }
220    }
221}
222