From cec8552b18fd74517512a43a8d75f64e64bd12c3 Mon Sep 17 00:00:00 2001
From: Jean Chalard <jchalard@google.com>
Date: Wed, 11 Apr 2012 21:29:53 +0900
Subject: [PATCH] Pass a parameter to the dict pack if we don't have a default
 dict

Also, optimize quite a bit the code that decides whether we have
a default dict or not.

Bug: 5705834
Change-Id: Ied20fbcbbc42cbe8c01759d11b1804d1156c6960
---
 .../latin/BinaryDictionaryFileDumper.java     | 27 +++++---
 .../latin/BinaryDictionaryGetter.java         |  4 +-
 .../inputmethod/latin/DictionaryFactory.java  | 62 ++++++-------------
 3 files changed, 42 insertions(+), 51 deletions(-)

diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java b/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java
index 311d3dc9d9..e4d081b561 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java
@@ -53,17 +53,23 @@ public class BinaryDictionaryFileDumper {
 
     private static final String DICTIONARY_PROJECTION[] = { "id" };
 
+    public static final String QUERY_PARAMETER_MAY_PROMPT_USER = "mayPrompt";
+    public static final String QUERY_PARAMETER_TRUE = "true";
+
     // Prevents this class to be accidentally instantiated.
     private BinaryDictionaryFileDumper() {
     }
 
     /**
-     * Return for a given locale or dictionary id the provider URI to get the dictionary.
+     * Returns a URI builder pointing to the dictionary pack.
+     *
+     * This creates a URI builder able to build a URI pointing to the dictionary
+     * pack content provider for a specific dictionary id.
      */
-    private static Uri getProviderUri(String path) {
+    private static Uri.Builder getProviderUriBuilder(final String path) {
         return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
                 .authority(BinaryDictionary.DICTIONARY_PACK_AUTHORITY).appendPath(
-                        path).build();
+                        path);
     }
 
     /**
@@ -71,9 +77,13 @@ public class BinaryDictionaryFileDumper {
      * available to copy into Latin IME.
      */
     private static List<WordListInfo> getWordListWordListInfos(final Locale locale,
-            final Context context) {
+            final Context context, final boolean hasDefaultWordList) {
         final ContentResolver resolver = context.getContentResolver();
-        final Uri dictionaryPackUri = getProviderUri(locale.toString());
+        final Uri.Builder builder = getProviderUriBuilder(locale.toString());
+        if (!hasDefaultWordList) {
+            builder.appendQueryParameter(QUERY_PARAMETER_MAY_PROMPT_USER, QUERY_PARAMETER_TRUE);
+        }
+        final Uri dictionaryPackUri = builder.build();
 
         final Cursor c = resolver.query(dictionaryPackUri, DICTIONARY_PROJECTION, null, null, null);
         if (null == c) return Collections.<WordListInfo>emptyList();
@@ -132,7 +142,7 @@ public class BinaryDictionaryFileDumper {
         final int MODE_MIN = COMPRESSED_CRYPTED_COMPRESSED;
         final int MODE_MAX = NONE;
 
-        final Uri wordListUri = getProviderUri(id);
+        final Uri wordListUri = getProviderUriBuilder(id).build();
         final String outputFileName = BinaryDictionaryGetter.getCacheFileName(id, locale, context);
 
         for (int mode = MODE_MIN; mode <= MODE_MAX; ++mode) {
@@ -231,9 +241,10 @@ public class BinaryDictionaryFileDumper {
      * @throw IOException if the provider-returned data could not be read.
      */
     public static List<AssetFileAddress> cacheWordListsFromContentProvider(final Locale locale,
-            final Context context) {
+            final Context context, final boolean hasDefaultWordList) {
         final ContentResolver resolver = context.getContentResolver();
-        final List<WordListInfo> idList = getWordListWordListInfos(locale, context);
+        final List<WordListInfo> idList = getWordListWordListInfos(locale, context,
+                hasDefaultWordList);
         final List<AssetFileAddress> fileAddressList = new ArrayList<AssetFileAddress>();
         for (WordListInfo id : idList) {
             final AssetFileAddress afd = cacheWordList(id.mId, id.mLocale, resolver, context);
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
index b0c2adc793..072dec9d1a 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
@@ -263,10 +263,12 @@ class BinaryDictionaryGetter {
     public static ArrayList<AssetFileAddress> getDictionaryFiles(final Locale locale,
             final Context context) {
 
+        final boolean hasDefaultWordList = DictionaryFactory.isDictionaryAvailable(context, locale);
         // cacheWordListsFromContentProvider returns the list of files it copied to local
         // storage, but we don't really care about what was copied NOW: what we want is the
         // list of everything we ever cached, so we ignore the return value.
-        BinaryDictionaryFileDumper.cacheWordListsFromContentProvider(locale, context);
+        BinaryDictionaryFileDumper.cacheWordListsFromContentProvider(locale, context,
+                hasDefaultWordList);
         final File[] cachedWordLists = getCachedWordLists(locale.toString(), context);
 
         final String mainDictId = getMainDictId(locale);
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFactory.java b/java/src/com/android/inputmethod/latin/DictionaryFactory.java
index bf05f3bc3a..17d75368ef 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFactory.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFactory.java
@@ -94,13 +94,14 @@ public class DictionaryFactory {
             final Locale locale) {
         AssetFileDescriptor afd = null;
         try {
-            final int resId = getMainDictionaryResourceId(context.getResources(), locale);
+            final int resId =
+                    getMainDictionaryResourceIdIfAvailableForLocale(context.getResources(), locale);
+            if (0 == resId) return null;
             afd = context.getResources().openRawResourceFd(resId);
             if (afd == null) {
                 Log.e(TAG, "Found the resource but it is compressed. resId=" + resId);
                 return null;
             }
-            if (!isFullDictionary(afd)) return null;
             final String sourceDir = context.getApplicationInfo().sourceDir;
             final File packagePath = new File(sourceDir);
             // TODO: Come up with a way to handle a directory.
@@ -152,55 +153,19 @@ public class DictionaryFactory {
      */
     public static boolean isDictionaryAvailable(Context context, Locale locale) {
         final Resources res = context.getResources();
-        final int resourceId = getMainDictionaryResourceId(res, locale);
-        final AssetFileDescriptor afd = res.openRawResourceFd(resourceId);
-        final boolean hasDictionary = isFullDictionary(afd);
-        try {
-            if (null != afd) afd.close();
-        } catch (java.io.IOException e) {
-            /* Um, what can we do here exactly? */
-        }
-        return hasDictionary;
-    }
-
-    // TODO: Do not use the size of the dictionary as an unique dictionary ID.
-    public static Long getDictionaryId(final Context context, final Locale locale) {
-        final Resources res = context.getResources();
-        final int resourceId = getMainDictionaryResourceId(res, locale);
-        final AssetFileDescriptor afd = res.openRawResourceFd(resourceId);
-        final Long size = (afd != null && afd.getLength() > PLACEHOLDER_LENGTH)
-                ? afd.getLength()
-                : null;
-        try {
-            if (null != afd) afd.close();
-        } catch (java.io.IOException e) {
-        }
-        return size;
-    }
-
-    // TODO: Find the Right Way to find out whether the resource is a placeholder or not.
-    // Suggestion : strip the locale, open the placeholder file and store its offset.
-    // Upon opening the file, if it's the same offset, then it's the placeholder.
-    private static final long PLACEHOLDER_LENGTH = 34;
-    /**
-     * Finds out whether the data pointed out by an AssetFileDescriptor is a full
-     * dictionary (as opposed to null, or to a place holder).
-     * @param afd the file descriptor to test, or null
-     * @return true if the dictionary is a real full dictionary, false if it's null or a placeholder
-     */
-    protected static boolean isFullDictionary(final AssetFileDescriptor afd) {
-        return (afd != null && afd.getLength() > PLACEHOLDER_LENGTH);
+        return 0 != getMainDictionaryResourceIdIfAvailableForLocale(res, locale);
     }
 
     private static final String DEFAULT_MAIN_DICT = "main";
     private static final String MAIN_DICT_PREFIX = "main_";
 
     /**
-     * Returns a main dictionary resource id
+     * Helper method to return a dictionary res id for a locale, or 0 if none.
      * @param locale dictionary locale
      * @return main dictionary resource id
      */
-    public static int getMainDictionaryResourceId(Resources res, Locale locale) {
+    private static int getMainDictionaryResourceIdIfAvailableForLocale(final Resources res,
+            final Locale locale) {
         final String packageName = LatinIME.class.getPackage().getName();
         int resId;
 
@@ -218,6 +183,19 @@ public class DictionaryFactory {
             return resId;
         }
 
+        // Not found, return 0
+        return 0;
+    }
+
+    /**
+     * Returns a main dictionary resource id
+     * @param locale dictionary locale
+     * @return main dictionary resource id
+     */
+    public static int getMainDictionaryResourceId(final Resources res, final Locale locale) {
+        int resourceId = getMainDictionaryResourceIdIfAvailableForLocale(res, locale);
+        if (0 != resourceId) return resourceId;
+        final String packageName = LatinIME.class.getPackage().getName();
         return res.getIdentifier(DEFAULT_MAIN_DICT, "raw", packageName);
     }
 }
-- 
GitLab