OSDN Git Service

Trebuchet: Use ICU4J public APIs
authorGabriele M <moto.falcon.git@gmail.com>
Sun, 19 Nov 2017 16:26:34 +0000 (17:26 +0100)
committerGabriele M <moto.falcon.git@gmail.com>
Sat, 25 Nov 2017 11:06:14 +0000 (11:06 +0000)
The private implementation of AlphabeticIndexCompat in libcore.icu
has been removed, so Trebuchet always uses BaseAlphabeticIndex,
which doesn't work properly with all the alphabets. Since Android
7.0, the Android platform exposes a subset of the ICU4J APIs, so
switch to that and drop the fallback code.

Change-Id: Id8e5538f70d074d5ffeea0c23ef3f2a72ec0f3bf

src/com/android/launcher3/compat/AlphabeticIndexCompat.java

index ee1f4d5..c954091 100644 (file)
 package com.android.launcher3.compat;
 
 import android.content.Context;
+import android.icu.text.AlphabeticIndex;
+
 import com.android.launcher3.Utilities;
 
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
-import java.text.Normalizer;
 import java.util.Locale;
 
-/**
- * Fallback class to support Alphabetic indexing if not supported by the framework.
- * TODO(winsonc): disable for non-english locales
- */
-class BaseAlphabeticIndex {
-
-    private static final String BUCKETS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-";
-    private static final int UNKNOWN_BUCKET_INDEX = BUCKETS.length() - 1;
-
-    public BaseAlphabeticIndex() {}
-
-    /**
-     * Sets the max number of the label buckets in this index.
-     */
-    public void setMaxLabelCount(int count) {
-        // Not currently supported
-    }
-
-    /**
-     * Returns the index of the bucket in which the given string should appear.
-     */
-    protected int getBucketIndex(String s) {
-        if (s.isEmpty()) {
-            return UNKNOWN_BUCKET_INDEX;
-        }
-        String asciiName = Normalizer.normalize(s, Normalizer.Form.NFD)
-            .replaceAll("[^\\p{ASCII}]", "");
-        if (asciiName.isEmpty()) {
-            return UNKNOWN_BUCKET_INDEX;
-        }
-        int index = BUCKETS.indexOf(asciiName.substring(0, 1).toUpperCase());
-        if (index != -1) {
-            return index;
-        }
-        return UNKNOWN_BUCKET_INDEX;
-    }
-
-    /**
-     * Returns the label for the bucket at the given index (as returned by getBucketIndex).
-     */
-    protected String getBucketLabel(int index) {
-        return BUCKETS.substring(index, index + 1);
-    }
-}
-
-/**
- * Reflected libcore.icu.AlphabeticIndex implementation, falls back to the base alphabetic index.
- */
-public class AlphabeticIndexCompat extends BaseAlphabeticIndex {
+public class AlphabeticIndexCompat {
 
     private static final String MID_DOT = "\u2219";
 
-    private Object mAlphabeticIndex;
-    private Method mAddLabelsMethod;
-    private Method mSetMaxLabelCountMethod;
-    private Method mGetBucketIndexMethod;
-    private Method mGetBucketLabelMethod;
-    private boolean mHasValidAlphabeticIndex;
+    private AlphabeticIndex.ImmutableIndex mAlphabeticIndex;
     private String mDefaultMiscLabel;
 
     public AlphabeticIndexCompat(Context context) {
-        super();
-        try {
-            Locale curLocale = context.getResources().getConfiguration().locale;
-            Class clazz = Class.forName("libcore.icu.AlphabeticIndex");
-            Constructor ctor = clazz.getConstructor(Locale.class);
-            mAddLabelsMethod = clazz.getDeclaredMethod("addLabels", Locale.class);
-            mSetMaxLabelCountMethod = clazz.getDeclaredMethod("setMaxLabelCount", int.class);
-            mGetBucketIndexMethod = clazz.getDeclaredMethod("getBucketIndex", String.class);
-            mGetBucketLabelMethod = clazz.getDeclaredMethod("getBucketLabel", int.class);
-            mAlphabeticIndex = ctor.newInstance(curLocale);
-            try {
-                // Ensure we always have some base English locale buckets
-                if (!curLocale.getLanguage().equals(Locale.ENGLISH.getLanguage())) {
-                    mAddLabelsMethod.invoke(mAlphabeticIndex, Locale.ENGLISH);
-                }
-            } catch (Exception e) {
-                e.printStackTrace();
-            }
-            if (curLocale.getLanguage().equals(Locale.JAPANESE.getLanguage())) {
-                // Japanese character 他 ("misc")
-                mDefaultMiscLabel = "\u4ed6";
-                // TODO(winsonc, omakoto): We need to handle Japanese sections better, especially the kanji
-            } else {
-                // Dot
-                mDefaultMiscLabel = MID_DOT;
-            }
-            mHasValidAlphabeticIndex = true;
-        } catch (Exception e) {
-            mHasValidAlphabeticIndex = false;
-        }
-    }
-
-    /**
-     * Sets the max number of the label buckets in this index.
-     * (ICU 51 default is 99)
-     */
-    public void setMaxLabelCount(int count) {
-        if (mHasValidAlphabeticIndex) {
-            try {
-                mSetMaxLabelCountMethod.invoke(mAlphabeticIndex, count);
-            } catch (Exception e) {
-                e.printStackTrace();
-            }
+        Locale curLocale = context.getResources().getConfiguration().getLocales().get(0);
+        mAlphabeticIndex = new AlphabeticIndex(curLocale).buildImmutableIndex();
+        if (curLocale.getLanguage().equals(Locale.JAPANESE.getLanguage())) {
+            // Japanese character 他 ("misc")
+            mDefaultMiscLabel = "\u4ed6";
+            // TODO(winsonc, omakoto): We need to handle Japanese sections better, especially the kanji
         } else {
-            super.setMaxLabelCount(count);
+            // Dot
+            mDefaultMiscLabel = MID_DOT;
         }
     }
 
@@ -122,7 +32,8 @@ public class AlphabeticIndexCompat extends BaseAlphabeticIndex {
      */
     public String computeSectionName(CharSequence cs) {
         String s = Utilities.trim(cs);
-        String sectionName = getBucketLabel(getBucketIndex(s));
+        int bucketIndex = mAlphabeticIndex.getBucketIndex(s);
+        String sectionName = mAlphabeticIndex.getBucket(bucketIndex).getLabel();
         if (Utilities.trim(sectionName).isEmpty()) {
             if (s.length() > 0) {
                 int c = s.codePointAt(0);
@@ -149,34 +60,4 @@ public class AlphabeticIndexCompat extends BaseAlphabeticIndex {
         }
         return sectionName;
     }
-
-    /**
-     * Returns the index of the bucket in which {@param s} should appear.
-     * Function is synchronized because underlying routine walks an iterator
-     * whose state is maintained inside the index object.
-     */
-    protected int getBucketIndex(String s) {
-        if (mHasValidAlphabeticIndex) {
-            try {
-                return (Integer) mGetBucketIndexMethod.invoke(mAlphabeticIndex, s);
-            } catch (Exception e) {
-                e.printStackTrace();
-            }
-        }
-        return super.getBucketIndex(s);
-    }
-
-    /**
-     * Returns the label for the bucket at the given index (as returned by getBucketIndex).
-     */
-    protected String getBucketLabel(int index) {
-        if (mHasValidAlphabeticIndex) {
-            try {
-                return (String) mGetBucketLabelMethod.invoke(mAlphabeticIndex, index);
-            } catch (Exception e) {
-                e.printStackTrace();
-            }
-        }
-        return super.getBucketLabel(index);
-    }
 }