BinaryDictionaryGetter.java revision 44861474fbea784f12fe86bc56d30d5d9be4ad81
1/* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 * use this file except in compliance with the License. You may obtain a copy of 6 * 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, WITHOUT 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 * License for the specific language governing permissions and limitations under 14 * the License. 15 */ 16 17package com.android.inputmethod.latin; 18 19import android.content.Context; 20import android.content.res.AssetFileDescriptor; 21import android.util.Log; 22 23import java.io.FileNotFoundException; 24import java.io.IOException; 25import java.util.Arrays; 26import java.util.List; 27import java.util.Locale; 28 29/** 30 * Helper class to get the address of a mmap'able dictionary file. 31 */ 32class BinaryDictionaryGetter { 33 34 /** 35 * Used for Log actions from this class 36 */ 37 private static final String TAG = BinaryDictionaryGetter.class.getSimpleName(); 38 39 // Prevents this from being instantiated 40 private BinaryDictionaryGetter() {} 41 42 /** 43 * Returns a file address from a resource, or null if it cannot be opened. 44 */ 45 private static AssetFileAddress loadFallbackResource(Context context, int fallbackResId) { 46 final AssetFileDescriptor afd = context.getResources().openRawResourceFd(fallbackResId); 47 if (afd == null) { 48 Log.e(TAG, "Found the resource but cannot read it. Is it compressed? resId=" 49 + fallbackResId); 50 return null; 51 } 52 return AssetFileAddress.makeFromFileNameAndOffset( 53 context.getApplicationInfo().sourceDir, afd.getStartOffset(), afd.getLength()); 54 } 55 56 /** 57 * Returns a list of file addresses for a given locale, trying relevant methods in order. 58 * 59 * Tries to get binary dictionaries from various sources, in order: 60 * - Uses a private method of getting a private dictionaries, as implemented by the 61 * PrivateBinaryDictionaryGetter class. 62 * If that fails: 63 * - Uses a content provider to get a public dictionary set, as per the protocol described 64 * in BinaryDictionaryFileDumper. 65 * If that fails: 66 * - Gets a file name from the fallback resource passed as an argument. 67 * If that fails: 68 * - Returns null. 69 * @return The address of a valid file, or null. 70 */ 71 public static List<AssetFileAddress> getDictionaryFiles(Locale locale, Context context, 72 int fallbackResId) { 73 // Try first to query a private package signed the same way for private files. 74 final List<AssetFileAddress> privateFiles = 75 PrivateBinaryDictionaryGetter.getDictionaryFiles(locale, context); 76 if (null != privateFiles) { 77 return privateFiles; 78 } else { 79 try { 80 // If that was no-go, try to find a publicly exported dictionary. 81 List<AssetFileAddress> listFromContentProvider = 82 BinaryDictionaryFileDumper.getDictSetFromContentProvider(locale, context); 83 if (null != listFromContentProvider) { 84 return listFromContentProvider; 85 } 86 // If the list is null, fall through and return the fallback 87 } catch (FileNotFoundException e) { 88 Log.e(TAG, "Unable to create dictionary file from provider for locale " 89 + locale.toString() + ": falling back to internal dictionary"); 90 } catch (IOException e) { 91 Log.e(TAG, "Unable to read source data for locale " 92 + locale.toString() + ": falling back to internal dictionary"); 93 } 94 final AssetFileAddress fallbackAsset = loadFallbackResource(context, fallbackResId); 95 if (null == fallbackAsset) return null; 96 return Arrays.asList(fallbackAsset); 97 } 98 } 99} 100