diff --git a/src/com/android/settings/search/SearchFeatureProviderImpl.java b/src/com/android/settings/search/SearchFeatureProviderImpl.java index 8c4883eecec..af7f1777d65 100644 --- a/src/com/android/settings/search/SearchFeatureProviderImpl.java +++ b/src/com/android/settings/search/SearchFeatureProviderImpl.java @@ -24,8 +24,11 @@ import android.util.Log; import com.android.settings.dashboard.SiteMapManager; import com.android.settings.overlay.FeatureFactory; +import com.android.settings.search.indexing.IndexData; import com.android.settingslib.wrapper.PackageManagerWrapper; +import java.util.Locale; + /** * FeatureProvider for the refactored search code. */ @@ -130,6 +133,9 @@ public class SearchFeatureProviderImpl implements SearchFeatureProvider { if (TextUtils.isEmpty(query)) { return null; } + if (Locale.getDefault().equals(Locale.JAPAN)) { + query = IndexData.normalizeJapaneseString(query); + } return query.trim(); } } diff --git a/src/com/android/settings/search/indexing/IndexData.java b/src/com/android/settings/search/indexing/IndexData.java index 9dad3fe5caf..33ea75e8cb9 100644 --- a/src/com/android/settings/search/indexing/IndexData.java +++ b/src/com/android/settings/search/indexing/IndexData.java @@ -29,6 +29,7 @@ import com.android.settings.search.ResultPayloadUtils; import com.android.settings.search.SearchIndexableResources; import java.text.Normalizer; +import java.util.Locale; import java.util.Objects; import java.util.regex.Pattern; @@ -69,9 +70,15 @@ public class IndexData { private IndexData(Builder builder) { locale = builder.mLocale; updatedTitle = normalizeHyphen(builder.mTitle); - normalizedTitle = normalizeString(builder.mTitle); updatedSummaryOn = normalizeHyphen(builder.mSummaryOn); - normalizedSummaryOn = normalizeString(builder.mSummaryOn); + if (Locale.JAPAN.toString().equalsIgnoreCase(locale)) { + // Special case for JP. Convert charset to the same type for indexing purpose. + normalizedTitle = normalizeJapaneseString(builder.mTitle); + normalizedSummaryOn = normalizeJapaneseString(builder.mSummaryOn); + } else { + normalizedTitle = normalizeString(builder.mTitle); + normalizedSummaryOn = normalizeString(builder.mSummaryOn); + } entries = builder.mEntries; className = builder.mClassName; childClassName = builder.mChildClassName; @@ -133,6 +140,24 @@ public class IndexData { return REMOVE_DIACRITICALS_PATTERN.matcher(normalized).replaceAll("").toLowerCase(); } + public static String normalizeJapaneseString(String input) { + final String nohyphen = (input != null) ? input.replaceAll(HYPHEN, EMPTY) : EMPTY; + final String normalized = Normalizer.normalize(nohyphen, Normalizer.Form.NFKD); + final StringBuffer sb = new StringBuffer(); + final int length = normalized.length(); + for (int i = 0; i < length; i++) { + char c = normalized.charAt(i); + // Convert Hiragana to full-width Katakana + if (c >= '\u3041' && c <= '\u3096') { + sb.append((char) (c - '\u3041' + '\u30A1')); + } else { + sb.append(c); + } + } + + return REMOVE_DIACRITICALS_PATTERN.matcher(sb.toString()).replaceAll("").toLowerCase(); + } + public static class Builder { private String mLocale; private String mTitle; @@ -273,8 +298,8 @@ public class IndexData { || TextUtils.equals(mIntentTargetPackage, SearchIndexableResources.SUBSETTING_TARGET_PACKAGE)) { // Action is null, we will launch it as a sub-setting - intent = DatabaseIndexingUtils.buildSearchResultPageIntent(context, mClassName, mKey, - mScreenTitle); + intent = DatabaseIndexingUtils.buildSearchResultPageIntent(context, mClassName, + mKey, mScreenTitle); } else { intent = new Intent(mIntentAction); final String targetClass = mIntentTargetClass; diff --git a/tests/robotests/src/com/android/settings/search/DatabaseIndexingUtilsTest.java b/tests/robotests/src/com/android/settings/search/DatabaseIndexingUtilsTest.java index 126abb91df8..9ce725b7764 100644 --- a/tests/robotests/src/com/android/settings/search/DatabaseIndexingUtilsTest.java +++ b/tests/robotests/src/com/android/settings/search/DatabaseIndexingUtilsTest.java @@ -94,4 +94,4 @@ public class DatabaseIndexingUtilsTest { ResultPayload payload = DatabaseIndexingUtils.getPayloadFromUriMap(map, key); assertThat(payload).isInstanceOf(ResultPayload.class); } -} \ No newline at end of file +} diff --git a/tests/robotests/src/com/android/settings/search/indexing/IndexDataTest.java b/tests/robotests/src/com/android/settings/search/indexing/IndexDataTest.java index ae9d99842c4..d33c0a71471 100644 --- a/tests/robotests/src/com/android/settings/search/indexing/IndexDataTest.java +++ b/tests/robotests/src/com/android/settings/search/indexing/IndexDataTest.java @@ -17,15 +17,17 @@ package com.android.settings.search.indexing; -import android.content.ComponentName; -import android.content.Intent; -import android.content.Context; +import static com.google.common.truth.Truth.assertThat; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; + +import com.android.settings.TestConfig; import com.android.settings.search.InlineSwitchPayload; import com.android.settings.search.ResultPayload; import com.android.settings.search.ResultPayloadUtils; import com.android.settings.testutils.SettingsRobolectricTestRunner; -import com.android.settings.TestConfig; import org.junit.Before; import org.junit.Test; @@ -33,8 +35,6 @@ import org.junit.runner.RunWith; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; -import static com.google.common.truth.Truth.assertThat; - @RunWith(SettingsRobolectricTestRunner.class) @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) public class IndexDataTest { @@ -141,6 +141,14 @@ public class IndexDataTest { assertThat(name.getPackageName()).isEqualTo(INTENT_TARGET_PACKAGE); } + @Test + public void testNormalizeJapaneseString() { + final String japaneseString = "\u3042\u3077\u308a"; + final String normalizedJapaneseString = "\u30a2\u30d5\u309a\u30ea"; + + String result = IndexData.normalizeJapaneseString(japaneseString); + assertThat(result).isEqualTo(normalizedJapaneseString); + } private IndexData generateRow() { return mBuilder.build(mContext);