Block offensive words in native code.

Bug: 15300452

Change-Id: Ic6c91c47453e19fb5db2c62b66659619e72b1ecf
Keisuke Kuroyanagi 2014-06-12 11:36:00 +09:00
parent d979d416c1
commit 59ed0c2db2
4 changed files with 26 additions and 16 deletions

View File

@ -292,6 +292,7 @@ public final class BinaryDictionary extends Dictionary {
} }
mNativeSuggestOptions.setIsGesture(isGesture); mNativeSuggestOptions.setIsGesture(isGesture);
mNativeSuggestOptions.setBlockOffensiveWords(blockOffensiveWords);
mNativeSuggestOptions.setAdditionalFeaturesOptions(additionalFeaturesOptions); mNativeSuggestOptions.setAdditionalFeaturesOptions(additionalFeaturesOptions);
if (inOutLanguageWeight != null) { if (inOutLanguageWeight != null) {
mInputOutputLanguageWeight[0] = inOutLanguageWeight[0]; mInputOutputLanguageWeight[0] = inOutLanguageWeight[0];
@ -319,18 +320,10 @@ public final class BinaryDictionary extends Dictionary {
++len; ++len;
} }
if (len > 0) { if (len > 0) {
final SuggestedWordInfo suggestedWordInfo = suggestions.add(new SuggestedWordInfo(new String(mOutputCodePoints, start, len),
new SuggestedWordInfo(new String(mOutputCodePoints, start, len), mOutputScores[j], mOutputTypes[j], this /* sourceDict */,
mOutputScores[j], mOutputTypes[j], this /* sourceDict */, mSpaceIndices[j] /* indexOfTouchPointOfSecondWord */,
mSpaceIndices[j] /* indexOfTouchPointOfSecondWord */, mOutputAutoCommitFirstWordConfidence[0]));
mOutputAutoCommitFirstWordConfidence[0]);
if (blockOffensiveWords && suggestedWordInfo.isPossiblyOffensive()
&& !suggestedWordInfo.isExactMatch()) {
// If we block potentially offensive words, and if the word is possibly
// offensive, then we don't output it unless it's also an exact match.
continue;
}
suggestions.add(suggestedWordInfo);
} }
} }
return suggestions; return suggestions;

View File

@ -20,7 +20,8 @@ public class NativeSuggestOptions {
// Need to update suggest_options.h when you add, remove or reorder options. // Need to update suggest_options.h when you add, remove or reorder options.
private static final int IS_GESTURE = 0; private static final int IS_GESTURE = 0;
private static final int USE_FULL_EDIT_DISTANCE = 1; private static final int USE_FULL_EDIT_DISTANCE = 1;
private static final int OPTIONS_SIZE = 2; private static final int BLOCK_OFFENSIVE_WORDS = 2;
private static final int OPTIONS_SIZE = 3;
private final int[] mOptions = new int[OPTIONS_SIZE private final int[] mOptions = new int[OPTIONS_SIZE
+ AdditionalFeaturesSettingUtils.ADDITIONAL_FEATURES_SETTINGS_SIZE]; + AdditionalFeaturesSettingUtils.ADDITIONAL_FEATURES_SETTINGS_SIZE];
@ -33,6 +34,10 @@ public class NativeSuggestOptions {
setBooleanOption(USE_FULL_EDIT_DISTANCE, value); setBooleanOption(USE_FULL_EDIT_DISTANCE, value);
} }
public void setBlockOffensiveWords(final boolean value) {
setBooleanOption(BLOCK_OFFENSIVE_WORDS, value);
}
public void setAdditionalFeaturesOptions(final int[] additionalOptions) { public void setAdditionalFeaturesOptions(final int[] additionalOptions) {
if (additionalOptions == null) { if (additionalOptions == null) {
return; return;

View File

@ -26,6 +26,7 @@
#include "suggest/core/policy/scoring.h" #include "suggest/core/policy/scoring.h"
#include "suggest/core/result/suggestion_results.h" #include "suggest/core/result/suggestion_results.h"
#include "suggest/core/session/dic_traverse_session.h" #include "suggest/core/session/dic_traverse_session.h"
#include "suggest/core/suggest_options.h"
namespace latinime { namespace latinime {
@ -105,6 +106,11 @@ const int SuggestionsOutputUtils::MIN_LEN_FOR_MULTI_WORD_AUTOCORRECT = 16;
// Entries that are blacklisted or do not represent a word should not be output. // Entries that are blacklisted or do not represent a word should not be output.
const bool isValidWord = !terminalDicNode->isBlacklistedOrNotAWord(); const bool isValidWord = !terminalDicNode->isBlacklistedOrNotAWord();
// When we have to block offensive words, non-exact matched offensive words should not be
// output.
const bool blockOffensiveWords = traverseSession->getSuggestOptions()->blockOffensiveWords();
const bool isBlockedOffensiveWord = blockOffensiveWords && isPossiblyOffensiveWord
&& !isSafeExactMatch;
// Increase output score of top typing suggestion to ensure autocorrection. // Increase output score of top typing suggestion to ensure autocorrection.
// TODO: Better integration with java side autocorrection logic. // TODO: Better integration with java side autocorrection logic.
@ -115,8 +121,9 @@ const int SuggestionsOutputUtils::MIN_LEN_FOR_MULTI_WORD_AUTOCORRECT = 16;
|| (isValidWord && scoringPolicy->doesAutoCorrectValidWord()), || (isValidWord && scoringPolicy->doesAutoCorrectValidWord()),
boostExactMatches); boostExactMatches);
// Don't output invalid words. However, we still need to submit their shortcuts if any. // Don't output invalid or blocked offensive words. However, we still need to submit their
if (isValidWord) { // shortcuts if any.
if (isValidWord && !isBlockedOffensiveWord) {
int codePoints[MAX_WORD_LENGTH]; int codePoints[MAX_WORD_LENGTH];
terminalDicNode->outputResult(codePoints); terminalDicNode->outputResult(codePoints);
const int indexToPartialCommit = outputSecondWordFirstLetterInputIndex ? const int indexToPartialCommit = outputSecondWordFirstLetterInputIndex ?

View File

@ -34,6 +34,10 @@ class SuggestOptions{
return getBoolOption(USE_FULL_EDIT_DISTANCE); return getBoolOption(USE_FULL_EDIT_DISTANCE);
} }
AK_FORCE_INLINE bool blockOffensiveWords() const {
return getBoolOption(BLOCK_OFFENSIVE_WORDS);
}
AK_FORCE_INLINE bool getAdditionalFeaturesBoolOption(const int key) const { AK_FORCE_INLINE bool getAdditionalFeaturesBoolOption(const int key) const {
return getBoolOption(key + ADDITIONAL_FEATURES_OPTIONS); return getBoolOption(key + ADDITIONAL_FEATURES_OPTIONS);
} }
@ -45,9 +49,10 @@ class SuggestOptions{
// reorder options. // reorder options.
static const int IS_GESTURE = 0; static const int IS_GESTURE = 0;
static const int USE_FULL_EDIT_DISTANCE = 1; static const int USE_FULL_EDIT_DISTANCE = 1;
static const int BLOCK_OFFENSIVE_WORDS = 2;
// Additional features options are stored after the other options and used as setting values of // Additional features options are stored after the other options and used as setting values of
// experimental features. // experimental features.
static const int ADDITIONAL_FEATURES_OPTIONS = 2; static const int ADDITIONAL_FEATURES_OPTIONS = 3;
const int *const mOptions; const int *const mOptions;
const int mLength; const int mLength;