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