1 /* 2 * Copyright (C) 2013 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 17 package com.android.inputmethod.latin; 18 19 import android.app.AlertDialog; 20 import android.content.Context; 21 import android.content.DialogInterface; 22 import android.content.DialogInterface.OnClickListener; 23 import android.os.Environment; 24 25 import com.android.inputmethod.latin.makedict.FormatSpec.FileHeader; 26 27 import java.io.BufferedInputStream; 28 import java.io.BufferedOutputStream; 29 import java.io.File; 30 import java.io.FileInputStream; 31 import java.io.FileOutputStream; 32 import java.io.IOException; 33 import java.util.ArrayList; 34 import java.util.Locale; 35 36 /** 37 * A class to read a local file as a dictionary for debugging purposes. 38 */ 39 public class ExternalDictionaryGetterForDebug { 40 private static final String SOURCE_FOLDER = Environment.getExternalStorageDirectory().getPath() 41 + "/Download"; 42 43 private static String[] findDictionariesInTheDownloadedFolder() { 44 final File[] files = new File(SOURCE_FOLDER).listFiles(); 45 final ArrayList<String> eligibleList = CollectionUtils.newArrayList(); 46 for (File f : files) { 47 final FileHeader header = DictionaryInfoUtils.getDictionaryFileHeaderOrNull(f); 48 if (null == header) continue; 49 eligibleList.add(f.getName()); 50 } 51 return eligibleList.toArray(new String[0]); 52 } 53 54 public static void chooseAndInstallDictionary(final Context context) { 55 final String[] fileNames = findDictionariesInTheDownloadedFolder(); 56 if (0 == fileNames.length) { 57 showNoFileDialog(context); 58 } else if (1 == fileNames.length) { 59 askInstallFile(context, fileNames[0]); 60 } else { 61 showChooseFileDialog(context, fileNames); 62 } 63 } 64 65 private static void showNoFileDialog(final Context context) { 66 new AlertDialog.Builder(context) 67 .setMessage(R.string.read_external_dictionary_no_files_message) 68 .setPositiveButton(android.R.string.ok, new OnClickListener() { 69 @Override 70 public void onClick(final DialogInterface dialog, final int which) { 71 dialog.dismiss(); 72 } 73 }).create().show(); 74 } 75 76 private static void showChooseFileDialog(final Context context, final String[] fileNames) { 77 final AlertDialog.Builder builder = new AlertDialog.Builder(context); 78 builder.setTitle(R.string.read_external_dictionary_multiple_files_title) 79 .setItems(fileNames, new OnClickListener() { 80 @Override 81 public void onClick(final DialogInterface dialog, final int which) { 82 askInstallFile(context, fileNames[which]); 83 } 84 }) 85 .create().show(); 86 } 87 88 private static void askInstallFile(final Context context, final String fileName) { 89 final File file = new File(SOURCE_FOLDER, fileName.toString()); 90 final FileHeader header = DictionaryInfoUtils.getDictionaryFileHeaderOrNull(file); 91 final StringBuilder message = new StringBuilder(); 92 final String locale = header.getLocaleString(); 93 for (String key : header.mDictionaryOptions.mAttributes.keySet()) { 94 message.append(key + " = " + header.mDictionaryOptions.mAttributes.get(key)); 95 message.append("\n"); 96 } 97 final String languageName = LocaleUtils.constructLocaleFromString(locale) 98 .getDisplayName(Locale.getDefault()); 99 final String title = String.format( 100 context.getString(R.string.read_external_dictionary_confirm_install_message), 101 languageName); 102 new AlertDialog.Builder(context) 103 .setTitle(title) 104 .setMessage(message) 105 .setNegativeButton(android.R.string.cancel, new OnClickListener() { 106 @Override 107 public void onClick(final DialogInterface dialog, final int which) { 108 dialog.dismiss(); 109 } 110 }).setPositiveButton(android.R.string.ok, new OnClickListener() { 111 @Override 112 public void onClick(final DialogInterface dialog, final int which) { 113 installFile(context, file, header); 114 dialog.dismiss(); 115 } 116 }).create().show(); 117 } 118 119 private static void installFile(final Context context, final File file, 120 final FileHeader header) { 121 BufferedOutputStream outputStream = null; 122 File tempFile = null; 123 try { 124 final String locale = header.getLocaleString(); 125 // Create the id for a main dictionary for this locale 126 final String id = BinaryDictionaryGetter.MAIN_DICTIONARY_CATEGORY 127 + BinaryDictionaryGetter.ID_CATEGORY_SEPARATOR + locale; 128 final String finalFileName = DictionaryInfoUtils.getCacheFileName(id, locale, context); 129 final String tempFileName = BinaryDictionaryGetter.getTempFileName(id, context); 130 tempFile = new File(tempFileName); 131 tempFile.delete(); 132 outputStream = new BufferedOutputStream(new FileOutputStream(tempFile)); 133 final BufferedInputStream bufferedStream = new BufferedInputStream( 134 new FileInputStream(file)); 135 BinaryDictionaryFileDumper.checkMagicAndCopyFileTo(bufferedStream, outputStream); 136 outputStream.flush(); 137 final File finalFile = new File(finalFileName); 138 finalFile.delete(); 139 if (!tempFile.renameTo(finalFile)) { 140 throw new IOException("Can't move the file to its final name"); 141 } 142 } catch (IOException e) { 143 // There was an error: show a dialog 144 new AlertDialog.Builder(context) 145 .setTitle(R.string.error) 146 .setMessage(e.toString()) 147 .setPositiveButton(android.R.string.ok, new OnClickListener() { 148 @Override 149 public void onClick(final DialogInterface dialog, final int which) { 150 dialog.dismiss(); 151 } 152 }).create().show(); 153 return; 154 } finally { 155 try { 156 if (null != outputStream) outputStream.close(); 157 if (null != tempFile) tempFile.delete(); 158 } catch (IOException e) { 159 // Don't do anything 160 } 161 } 162 } 163 } 164