10b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka/*
20b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka * Copyright (C) 2017 The Android Open Source Project
30b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka *
40b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka * Licensed under the Apache License, Version 2.0 (the "License");
50b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka * you may not use this file except in compliance with the License.
60b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka * You may obtain a copy of the License at
70b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka *
80b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka *      http://www.apache.org/licenses/LICENSE-2.0
90b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka *
100b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka * Unless required by applicable law or agreed to in writing, software
110b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka * distributed under the License is distributed on an "AS IS" BASIS,
120b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka * See the License for the specific language governing permissions and
140b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka * limitations under the License.
150b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka */
160b03693667d95d2202dfbb24866665ff061acce1Seigo Nonakapackage android.support.v4.provider;
170b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka
180b03693667d95d2202dfbb24866665ff061acce1Seigo Nonakaimport static android.support.v4.provider.FontsContractCompat.Columns.RESULT_CODE_FONT_NOT_FOUND;
190b03693667d95d2202dfbb24866665ff061acce1Seigo Nonakaimport static android.support.v4.provider.FontsContractCompat.Columns.RESULT_CODE_FONT_UNAVAILABLE;
200b03693667d95d2202dfbb24866665ff061acce1Seigo Nonakaimport static android.support.v4.provider.FontsContractCompat.Columns.RESULT_CODE_MALFORMED_QUERY;
210b03693667d95d2202dfbb24866665ff061acce1Seigo Nonakaimport static android.support.v4.provider.FontsContractCompat.Columns.RESULT_CODE_OK;
220b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka
23c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarriimport static org.junit.Assert.assertEquals;
24c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarriimport static org.junit.Assert.assertNotNull;
25c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarriimport static org.junit.Assert.assertNotSame;
26c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarriimport static org.junit.Assert.assertNull;
27c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarriimport static org.junit.Assert.assertTrue;
28c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarriimport static org.junit.Assert.fail;
290b03693667d95d2202dfbb24866665ff061acce1Seigo Nonakaimport static org.mockito.Matchers.anyInt;
300b03693667d95d2202dfbb24866665ff061acce1Seigo Nonakaimport static org.mockito.Matchers.anyString;
310b03693667d95d2202dfbb24866665ff061acce1Seigo Nonakaimport static org.mockito.Mockito.mock;
320b03693667d95d2202dfbb24866665ff061acce1Seigo Nonakaimport static org.mockito.Mockito.when;
330b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka
34c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarriimport android.app.Instrumentation;
35c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarriimport android.content.Context;
360b03693667d95d2202dfbb24866665ff061acce1Seigo Nonakaimport android.content.pm.ApplicationInfo;
370b03693667d95d2202dfbb24866665ff061acce1Seigo Nonakaimport android.content.pm.PackageInfo;
380b03693667d95d2202dfbb24866665ff061acce1Seigo Nonakaimport android.content.pm.PackageManager;
390b03693667d95d2202dfbb24866665ff061acce1Seigo Nonakaimport android.content.pm.PackageManager.NameNotFoundException;
400b03693667d95d2202dfbb24866665ff061acce1Seigo Nonakaimport android.content.pm.ProviderInfo;
410b03693667d95d2202dfbb24866665ff061acce1Seigo Nonakaimport android.content.pm.Signature;
42c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarriimport android.graphics.Typeface;
43c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarriimport android.support.test.InstrumentationRegistry;
440b03693667d95d2202dfbb24866665ff061acce1Seigo Nonakaimport android.support.test.filters.SmallTest;
45c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarriimport android.support.test.runner.AndroidJUnit4;
46c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarriimport android.support.v4.provider.FontsContractCompat.FontFamilyResult;
470b03693667d95d2202dfbb24866665ff061acce1Seigo Nonakaimport android.support.v4.provider.FontsContractCompat.FontInfo;
480b03693667d95d2202dfbb24866665ff061acce1Seigo Nonakaimport android.util.Base64;
490b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka
50c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarriimport org.junit.After;
51c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarriimport org.junit.Before;
52c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarriimport org.junit.Test;
53c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarriimport org.junit.runner.RunWith;
54c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri
550b03693667d95d2202dfbb24866665ff061acce1Seigo Nonakaimport java.util.ArrayList;
560b03693667d95d2202dfbb24866665ff061acce1Seigo Nonakaimport java.util.Arrays;
570b03693667d95d2202dfbb24866665ff061acce1Seigo Nonakaimport java.util.Collections;
580b03693667d95d2202dfbb24866665ff061acce1Seigo Nonakaimport java.util.List;
590b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka
600b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka/**
61c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri * Unit tests for {@link FontsContractCompat}.
620b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka */
63c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri@RunWith(AndroidJUnit4.class)
640b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka@SmallTest
65c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarripublic class FontsContractCompatTest {
66d53f7ac99a32900c6cc193a4cf8f93eaddde54ddClara Bayarri    private static final String AUTHORITY = "android.support.provider.fonts.font";
67c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri    private static final String PACKAGE = "android.support.compat.test";
68c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri
69c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri    // Signature to be used for authentication to access content provider.
70c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri    // In this test case, the content provider and consumer live in the same package, self package's
71c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri    // signature works.
72c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri    private static final List<List<byte[]>> SIGNATURE;
73c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri    static {
74c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        final Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
75c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        try {
76c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri            PackageManager manager = context.getPackageManager();
77c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri            PackageInfo info = manager.getPackageInfo(
78c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri                    context.getPackageName(), PackageManager.GET_SIGNATURES);
79c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri            ArrayList<byte[]> out = new ArrayList<>();
80c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri            for (Signature sig : info.signatures) {
81c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri                out.add(sig.toByteArray());
82c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri            }
83c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri            SIGNATURE = new ArrayList<>();
84c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri            SIGNATURE.add(out);
85c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        } catch (PackageManager.NameNotFoundException e) {
86c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri            throw new RuntimeException(e);
87c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        }
88c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri    }
89c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri
900b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka    private static final byte[] BYTE_ARRAY =
910b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka            Base64.decode("e04fd020ea3a6910a2d808002b30", Base64.DEFAULT);
920b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka    // Use a different instance to test byte array comparison
930b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka    private static final byte[] BYTE_ARRAY_COPY =
940b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka            Base64.decode("e04fd020ea3a6910a2d808002b30", Base64.DEFAULT);
950b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka    private static final byte[] BYTE_ARRAY_2 =
960b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka            Base64.decode("e04fd020ea3a6910a2d808002b32", Base64.DEFAULT);
97c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri    private Instrumentation mInstrumentation;
98c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri    private Context mContext;
990b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka
100c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri    @Before
101c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri    public void setUp() throws Exception {
102c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        mInstrumentation = InstrumentationRegistry.getInstrumentation();
103c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        mContext = mInstrumentation.getTargetContext();
104c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        MockFontProvider.prepareFontFiles(
105c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri                InstrumentationRegistry.getInstrumentation().getTargetContext());
106c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri    }
1070b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka
108c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri    @After
109c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri    public void tearDown() {
110c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        MockFontProvider.cleanUpFontFiles(
111c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri                InstrumentationRegistry.getInstrumentation().getTargetContext());
1120b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka    }
1130b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka
114c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri    private static class TestCallback extends FontsContractCompat.FontRequestCallback {
115c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        private Typeface mTypeface;
116c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri
117c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        private int mSuccessCallCount;
118c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        private int mFailedCallCount;
119c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri
120c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        public void onTypefaceRetrieved(Typeface typeface) {
121c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri            mTypeface = typeface;
122c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri            mSuccessCallCount++;
123c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        }
124c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri
125c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        public void onTypefaceRequestFailed(int reason) {
126c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri            mFailedCallCount++;
127c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        }
128c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri
129c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        public Typeface getTypeface() {
130c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri            return mTypeface;
131c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        }
132c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri
133c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        public int getSuccessCallCount() {
134c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri            return mSuccessCallCount;
135c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        }
1360b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka
137c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        public int getFailedCallCount() {
138c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri            return mFailedCallCount;
139c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        }
1400b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka    }
1410b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka
142c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri    @Test
143c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri    public void typefaceNotCacheTest() throws NameNotFoundException {
144c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        FontRequest request = new FontRequest(
145c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri                AUTHORITY, PACKAGE, MockFontProvider.SINGLE_FONT_FAMILY_QUERY, SIGNATURE);
146c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        FontFamilyResult result = FontsContractCompat.fetchFonts(
147c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri                mContext, null /* cancellation signal */, request);
148c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        assertEquals(FontFamilyResult.STATUS_OK, result.getStatusCode());
149c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        Typeface typeface = FontsContractCompat.buildTypeface(
150c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri                mContext, null /* cancellation signal */, result.getFonts());
151c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri
152c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        FontFamilyResult result2 = FontsContractCompat.fetchFonts(
153c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri                mContext, null /* cancellation signal */, request);
154c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        assertEquals(FontFamilyResult.STATUS_OK, result2.getStatusCode());
155c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        Typeface typeface2 = FontsContractCompat.buildTypeface(
156c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri                mContext, null /* cancellation signal */, result2.getFonts());
157c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri
158c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        // Neither fetchFonts nor buildTypeface should cache the Typeface.
159c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        assertNotSame(typeface, typeface2);
160c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri    }
161c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri
162c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri    @Test
1630b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka    public void testGetFontFromProvider_resultOK() {
164c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        FontRequest request = new FontRequest(
165c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri                AUTHORITY, PACKAGE, MockFontProvider.SINGLE_FONT_FAMILY2_QUERY, SIGNATURE);
1660b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        FontInfo[] fonts = FontsContractCompat.getFontFromProvider(
167c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri                mContext, request, AUTHORITY, null);
1680b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        assertNotNull(fonts);
1690b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        assertEquals(1, fonts.length);
1700b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        FontInfo font = fonts[0];
171c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        assertEquals(0, font.getTtcIndex());
172c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        assertEquals(700, font.getWeight());
173c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        assertTrue(font.isItalic());
1740b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        assertNotNull(font.getUri());
1750b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        assertEquals(RESULT_CODE_OK, font.getResultCode());
1760b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka    }
1770b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka
178c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri    @Test
1790b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka    public void testGetFontFromProvider_providerDoesntReturnAllFields() {
180c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        FontRequest request = new FontRequest(
181c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri                AUTHORITY, PACKAGE, MockFontProvider.MANDATORY_FIELDS_ONLY_QUERY, SIGNATURE);
1820b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        FontInfo[] fonts = FontsContractCompat.getFontFromProvider(
183c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri                mContext, request, AUTHORITY, null);
1840b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        assertNotNull(fonts);
1850b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        assertEquals(1, fonts.length);
1860b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        FontInfo font = fonts[0];
1870b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        assertEquals(0, font.getTtcIndex());
1880b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        assertEquals(RESULT_CODE_OK, font.getResultCode());
1890b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka    }
1900b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka
191c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri    @Test
1920b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka    public void testGetFontFromProvider_resultFontNotFound() {
193c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        FontRequest request = new FontRequest(
194c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri                AUTHORITY, PACKAGE, MockFontProvider.NOT_FOUND_QUERY, SIGNATURE);
1950b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        FontInfo[] fonts = FontsContractCompat.getFontFromProvider(
196c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri                mContext, request, AUTHORITY, null);
1970b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        assertNotNull(fonts);
1980b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        assertEquals(1, fonts.length);
1990b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        FontInfo font = fonts[0];
2000b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        assertEquals(RESULT_CODE_FONT_NOT_FOUND, font.getResultCode());
2010b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka    }
2020b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka
203c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri    @Test
2040b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka    public void testGetFontFromProvider_resultFontUnavailable() {
205c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        FontRequest request = new FontRequest(
206c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri                AUTHORITY, PACKAGE, MockFontProvider.UNAVAILABLE_QUERY, SIGNATURE);
2070b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        FontInfo[] fonts = FontsContractCompat.getFontFromProvider(
208c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri                mContext, request, AUTHORITY, null);
2090b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka
2100b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        assertNotNull(fonts);
2110b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        assertEquals(1, fonts.length);
2120b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        FontInfo font = fonts[0];
2130b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        assertEquals(RESULT_CODE_FONT_UNAVAILABLE, font.getResultCode());
2140b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka    }
2150b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka
216c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri    @Test
2170b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka    public void testGetFontFromProvider_resultMalformedQuery() {
218c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        FontRequest request = new FontRequest(
219c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri                AUTHORITY, PACKAGE, MockFontProvider.MALFORMED_QUERY, SIGNATURE);
2200b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        FontInfo[] fonts = FontsContractCompat.getFontFromProvider(
221c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri                mContext, request, AUTHORITY, null);
2220b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka
2230b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        assertNotNull(fonts);
2240b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        assertEquals(1, fonts.length);
2250b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        FontInfo font = fonts[0];
2260b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        assertEquals(RESULT_CODE_MALFORMED_QUERY, font.getResultCode());
2270b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka    }
2280b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka
229c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri    @Test
2300b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka    public void testGetFontFromProvider_resultFontNotFoundSecondRow() {
231c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        FontRequest request = new FontRequest(
232c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri                AUTHORITY, PACKAGE, MockFontProvider.NOT_FOUND_SECOND_QUERY, SIGNATURE);
2330b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        FontInfo[] fonts = FontsContractCompat.getFontFromProvider(
234c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri                mContext, request, AUTHORITY, null);
2350b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka
2360b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        assertNotNull(fonts);
2370b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        assertEquals(2, fonts.length);
2380b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka
2390b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        FontInfo font = fonts[0];
2400b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        assertEquals(RESULT_CODE_OK, font.getResultCode());
2410b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka
2420b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        font = fonts[1];
2430b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        assertEquals(RESULT_CODE_FONT_NOT_FOUND, font.getResultCode());
2440b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka    }
2450b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka
246c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri    @Test
2470b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka    public void testGetFontFromProvider_resultFontNotFoundOtherRow() {
248c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        FontRequest request = new FontRequest(
249c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri                AUTHORITY, PACKAGE, MockFontProvider.NOT_FOUND_THIRD_QUERY, SIGNATURE);
2500b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        FontInfo[] fonts = FontsContractCompat.getFontFromProvider(
251c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri                mContext, request, AUTHORITY, null);
2520b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka
2530b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        assertNotNull(fonts);
2540b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        assertEquals(3, fonts.length);
2550b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka
2560b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        FontInfo font = fonts[0];
2570b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        assertEquals(RESULT_CODE_OK, font.getResultCode());
2580b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka
2590b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        font = fonts[1];
2600b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        assertEquals(RESULT_CODE_FONT_NOT_FOUND, font.getResultCode());
2610b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka
2620b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        font = fonts[2];
2630b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        assertEquals(RESULT_CODE_OK, font.getResultCode());
2640b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka    }
2650b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka
266c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri    public void testGetFontFromProvider_resultCodeIsNegativeNumber() {
267c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        FontRequest request = new FontRequest(
268c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri                AUTHORITY, PACKAGE, MockFontProvider.NEGATIVE_ERROR_CODE_QUERY, SIGNATURE);
269c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        FontInfo[] fonts = FontsContractCompat.getFontFromProvider(
270c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri                mContext, request, AUTHORITY, null);
2710b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka
2720b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka
273c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        assertNotNull(fonts);
274c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        assertEquals(1, fonts.length);
275c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        FontInfo font = fonts[0];
276c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        assertEquals(RESULT_CODE_FONT_NOT_FOUND, font.getResultCode());
2770b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka    }
2780b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka
279c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri    @Test
280c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri    public void testGetProvider_providerNotFound() {
281c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        PackageManager packageManager = mock(PackageManager.class);
282c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        when(packageManager.resolveContentProvider(anyString(), anyInt())).thenReturn(null);
2830b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka
284c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        FontRequest request = new FontRequest(AUTHORITY, PACKAGE, "query", SIGNATURE);
2850b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        try {
286c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri            FontsContractCompat.getProvider(packageManager, request, null);
2870b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka            fail();
2880b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        } catch (NameNotFoundException e) {
2890b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka            // pass
2900b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        }
2910b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka    }
2920b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka
293c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri    @Test
294c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri    public void testGetProvider_noCerts()
2950b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka            throws PackageManager.NameNotFoundException {
296c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        PackageManager packageManager = mContext.getPackageManager();
2970b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka
2980b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        List<List<byte[]>> emptyList = Collections.emptyList();
2990b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka
300c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        FontRequest request = new FontRequest(AUTHORITY, PACKAGE, "query", emptyList);
301c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        assertNull(FontsContractCompat.getProvider(packageManager, request, null));
3020b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka    }
3030b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka
304c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri    @Test
305c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri    public void testGetProvider_wrongCerts()
3060b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka            throws PackageManager.NameNotFoundException {
307c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        PackageManager packageManager = mock(PackageManager.class);
308c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        setupPackageManager(packageManager);
3090b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka
3100b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        byte[] wrongCert = Base64.decode("this is a wrong cert", Base64.DEFAULT);
3110b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        List<byte[]> certList = Arrays.asList(wrongCert);
3120b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        FontRequest requestWrongCerts = new FontRequest(
313c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri                AUTHORITY, PACKAGE, "query", Arrays.asList(certList));
3140b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka
315c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        assertNull(FontsContractCompat.getProvider(packageManager, requestWrongCerts, null));
3160b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka    }
3170b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka
318c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri    @Test
319c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri    public void testGetProvider_correctCerts()
3200b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka            throws PackageManager.NameNotFoundException {
321c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        PackageManager packageManager = mock(PackageManager.class);
322c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        ProviderInfo info = setupPackageManager(packageManager);
3230b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka
3240b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        List<byte[]> certList = Arrays.asList(BYTE_ARRAY);
3250b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        FontRequest requestRightCerts = new FontRequest(
326c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri                AUTHORITY, PACKAGE, "query", Arrays.asList(certList));
327c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        ProviderInfo result =
328c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri                FontsContractCompat.getProvider(packageManager, requestRightCerts, null);
3290b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka
3300b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        assertEquals(info, result);
3310b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka    }
3320b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka
333c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri    @Test
334c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri    public void testGetProvider_moreCerts()
3350b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka            throws PackageManager.NameNotFoundException {
336c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        PackageManager packageManager = mock(PackageManager.class);
337c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        setupPackageManager(packageManager);
3380b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka
3390b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        byte[] wrongCert = Base64.decode("this is a wrong cert", Base64.DEFAULT);
3400b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        List<byte[]> certList = Arrays.asList(wrongCert, BYTE_ARRAY);
3410b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        FontRequest requestRightCerts = new FontRequest(
342c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri                AUTHORITY, PACKAGE, "query", Arrays.asList(certList));
343c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        assertNull(FontsContractCompat.getProvider(packageManager, requestRightCerts, null));
3440b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka    }
3450b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka
346c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri    @Test
347c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri    public void testGetProvider_duplicateCerts()
3480b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka            throws PackageManager.NameNotFoundException {
349c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        PackageManager packageManager = mock(PackageManager.class);
350c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        setupPackageManager(packageManager);
3510b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        PackageInfo packageInfo = new PackageInfo();
3520b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        Signature signature = mock(Signature.class);
3530b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        when(signature.toByteArray()).thenReturn(BYTE_ARRAY_COPY);
3540b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        Signature signature2 = mock(Signature.class);
3550b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        when(signature2.toByteArray()).thenReturn(BYTE_ARRAY_COPY);
356c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        packageInfo.packageName = PACKAGE;
3570b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        packageInfo.signatures = new Signature[] { signature, signature2 };
358c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        when(packageManager.getPackageInfo(anyString(), anyInt())).thenReturn(packageInfo);
3590b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka
3600b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        // The provider has {BYTE_ARRAY_COPY, BYTE_ARRAY_COPY}, the request has
3610b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        // {BYTE_ARRAY_2, BYTE_ARRAY_COPY}.
3620b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        List<byte[]> certList = Arrays.asList(BYTE_ARRAY_2, BYTE_ARRAY_COPY);
3630b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        FontRequest requestRightCerts = new FontRequest(
364c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri                AUTHORITY, PACKAGE, "query", Arrays.asList(certList));
365c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        assertNull(FontsContractCompat.getProvider(packageManager, requestRightCerts, null));
3660b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka    }
3670b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka
368c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri    @Test
369c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri    public void testGetProvider_correctCertsSeveralSets()
3700b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka            throws PackageManager.NameNotFoundException {
371c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        PackageManager packageManager = mock(PackageManager.class);
372c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        ProviderInfo info = setupPackageManager(packageManager);
3730b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka
3740b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        List<List<byte[]>> certList = new ArrayList<>();
3750b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        byte[] wrongCert = Base64.decode("this is a wrong cert", Base64.DEFAULT);
3760b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        certList.add(Arrays.asList(wrongCert));
3770b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        certList.add(Arrays.asList(BYTE_ARRAY));
378c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        FontRequest requestRightCerts = new FontRequest(AUTHORITY, PACKAGE, "query", certList);
3790b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        ProviderInfo result =
380c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri                FontsContractCompat.getProvider(packageManager, requestRightCerts, null);
3810b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka
3820b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        assertEquals(info, result);
3830b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka    }
3840b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka
385c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri    @Test
386c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri    public void testGetProvider_wrongPackage()
3870b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka            throws PackageManager.NameNotFoundException {
388c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        PackageManager packageManager = mContext.getPackageManager();
3890b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka
3900b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        List<List<byte[]>> certList = new ArrayList<>();
3910b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        certList.add(Arrays.asList(BYTE_ARRAY));
3920b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        FontRequest requestRightCerts = new FontRequest(
393c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri                AUTHORITY, "com.wrong.package.name", "query", certList);
3940b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        try {
395c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri            FontsContractCompat.getProvider(packageManager, requestRightCerts, null);
3960b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka            fail();
3970b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        } catch (NameNotFoundException e) {
3980b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka            // pass
3990b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        }
4000b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka    }
4010b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka
402c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri    private ProviderInfo setupPackageManager(PackageManager packageManager)
4030b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka            throws PackageManager.NameNotFoundException {
4040b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        ProviderInfo info = new ProviderInfo();
405c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        info.packageName = PACKAGE;
4060b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        info.applicationInfo = new ApplicationInfo();
407c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        when(packageManager.resolveContentProvider(anyString(), anyInt())).thenReturn(info);
4080b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        PackageInfo packageInfo = new PackageInfo();
4090b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        Signature signature = mock(Signature.class);
4100b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        when(signature.toByteArray()).thenReturn(BYTE_ARRAY_COPY);
411c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        packageInfo.packageName = PACKAGE;
4120b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        packageInfo.signatures = new Signature[] { signature };
413c357691d3aae8bb2913941267188e12594d5ca80Clara Bayarri        when(packageManager.getPackageInfo(anyString(), anyInt())).thenReturn(packageInfo);
4140b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka        return info;
4150b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka    }
4160b03693667d95d2202dfbb24866665ff061acce1Seigo Nonaka}
417