Merge changes from topic "am-8e5146ce-8d9c-4779-ae0e-dfd45eb1f559"
* changes:
[automerger] Remove use of @hide and RestrictTo in ArraySet. am: 1d6b134dfe
Remove use of @hide and RestrictTo in ArraySet.
diff --git a/emoji/core/api/current.txt b/emoji/core/api/current.txt
index d5ce666..40bd7d8 100644
--- a/emoji/core/api/current.txt
+++ b/emoji/core/api/current.txt
@@ -32,6 +32,8 @@
method public android.support.text.emoji.EmojiCompat.Config setEmojiSpanIndicatorColor(int);
method public android.support.text.emoji.EmojiCompat.Config setEmojiSpanIndicatorEnabled(boolean);
method public android.support.text.emoji.EmojiCompat.Config setReplaceAll(boolean);
+ method public android.support.text.emoji.EmojiCompat.Config setUseEmojiAsDefaultStyle(boolean);
+ method public android.support.text.emoji.EmojiCompat.Config setUseEmojiAsDefaultStyle(boolean, java.util.List<java.lang.Integer>);
method public android.support.text.emoji.EmojiCompat.Config unregisterInitCallback(android.support.text.emoji.EmojiCompat.InitCallback);
}
diff --git a/emoji/core/src/main/java/android/support/text/emoji/EmojiCompat.java b/emoji/core/src/main/java/android/support/text/emoji/EmojiCompat.java
index 5436aa2..413a9dd 100644
--- a/emoji/core/src/main/java/android/support/text/emoji/EmojiCompat.java
+++ b/emoji/core/src/main/java/android/support/text/emoji/EmojiCompat.java
@@ -184,6 +184,16 @@
private final boolean mReplaceAll;
/**
+ * @see Config#setUseEmojiAsDefaultStyle(boolean)
+ */
+ private final boolean mUseEmojiAsDefaultStyle;
+
+ /**
+ * @see Config#setUseEmojiAsDefaultStyle(boolean, List)
+ */
+ private final int[] mEmojiAsDefaultStyleExceptions;
+
+ /**
* @see Config#setEmojiSpanIndicatorEnabled(boolean)
*/
private final boolean mEmojiSpanIndicatorEnabled;
@@ -201,6 +211,8 @@
private EmojiCompat(@NonNull final Config config) {
mInitLock = new ReentrantReadWriteLock();
mReplaceAll = config.mReplaceAll;
+ mUseEmojiAsDefaultStyle = config.mUseEmojiAsDefaultStyle;
+ mEmojiAsDefaultStyleExceptions = config.mEmojiAsDefaultStyleExceptions;
mEmojiSpanIndicatorEnabled = config.mEmojiSpanIndicatorEnabled;
mEmojiSpanIndicatorColor = config.mEmojiSpanIndicatorColor;
mMetadataLoader = config.mMetadataLoader;
@@ -787,6 +799,8 @@
public abstract static class Config {
private final MetadataRepoLoader mMetadataLoader;
private boolean mReplaceAll;
+ private boolean mUseEmojiAsDefaultStyle;
+ private int[] mEmojiAsDefaultStyleExceptions;
private Set<InitCallback> mInitCallbacks;
private boolean mEmojiSpanIndicatorEnabled;
private int mEmojiSpanIndicatorColor = Color.GREEN;
@@ -849,6 +863,56 @@
}
/**
+ * Determines whether EmojiCompat should use the emoji presentation style for emojis
+ * that have text style as default. By default, the text style would be used, unless these
+ * are followed by the U+FE0F variation selector.
+ * Details about emoji presentation and text presentation styles can be found here:
+ * http://unicode.org/reports/tr51/#Presentation_Style
+ * If useEmojiAsDefaultStyle is true, the emoji presentation style will be used for all
+ * emojis, including potentially unexpected ones (such as digits or other keycap emojis). If
+ * this is not the expected behaviour, method
+ * {@link #setUseEmojiAsDefaultStyle(boolean, List)} can be used to specify the
+ * exception emojis that should be still presented as text style.
+ *
+ * @param useEmojiAsDefaultStyle whether to use the emoji style presentation for all emojis
+ * that would be presented as text style by default
+ */
+ public Config setUseEmojiAsDefaultStyle(final boolean useEmojiAsDefaultStyle) {
+ return setUseEmojiAsDefaultStyle(useEmojiAsDefaultStyle, null);
+ }
+
+ /**
+ * @see #setUseEmojiAsDefaultStyle(boolean)
+ *
+ * @param emojiAsDefaultStyleExceptions Contains the exception emojis which will be still
+ * presented as text style even if the
+ * useEmojiAsDefaultStyle flag is set to {@code true}.
+ * This list will be ignored if useEmojiAsDefaultStyle
+ * is {@code false}. Note that emojis with default
+ * emoji style presentation will remain emoji style
+ * regardless the value of useEmojiAsDefaultStyle or
+ * whether they are included in the exceptions list or
+ * not. When no exception is wanted, the method
+ * {@link #setUseEmojiAsDefaultStyle(boolean)} should
+ * be used instead.
+ */
+ public Config setUseEmojiAsDefaultStyle(final boolean useEmojiAsDefaultStyle,
+ @Nullable final List<Integer> emojiAsDefaultStyleExceptions) {
+ mUseEmojiAsDefaultStyle = useEmojiAsDefaultStyle;
+ if (mUseEmojiAsDefaultStyle && emojiAsDefaultStyleExceptions != null) {
+ mEmojiAsDefaultStyleExceptions = new int[emojiAsDefaultStyleExceptions.size()];
+ int i = 0;
+ for (Integer exception : emojiAsDefaultStyleExceptions) {
+ mEmojiAsDefaultStyleExceptions[i++] = exception;
+ }
+ Arrays.sort(mEmojiAsDefaultStyleExceptions);
+ } else {
+ mEmojiAsDefaultStyleExceptions = null;
+ }
+ return this;
+ }
+
+ /**
* Determines whether a background will be drawn for the emojis that are found and
* replaced by EmojiCompat. Should be used only for debugging purposes. The indicator color
* can be set using {@link #setEmojiSpanIndicatorColor(int)}.
@@ -1020,7 +1084,9 @@
}
mMetadataRepo = metadataRepo;
- mProcessor = new EmojiProcessor(mMetadataRepo, new SpanFactory());
+ mProcessor = new EmojiProcessor(mMetadataRepo, new SpanFactory(),
+ mEmojiCompat.mUseEmojiAsDefaultStyle,
+ mEmojiCompat.mEmojiAsDefaultStyleExceptions);
mEmojiCompat.onMetadataLoadSuccess();
}
diff --git a/emoji/core/src/main/java/android/support/text/emoji/EmojiProcessor.java b/emoji/core/src/main/java/android/support/text/emoji/EmojiProcessor.java
index 3feb36d..f711704 100644
--- a/emoji/core/src/main/java/android/support/text/emoji/EmojiProcessor.java
+++ b/emoji/core/src/main/java/android/support/text/emoji/EmojiProcessor.java
@@ -22,6 +22,7 @@
import android.support.annotation.IntDef;
import android.support.annotation.IntRange;
import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.support.annotation.RestrictTo;
import android.support.text.emoji.widget.SpannableBuilder;
@@ -40,6 +41,8 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.Arrays;
+import java.util.List;
/**
* Processes the CharSequence and adds the emojis.
@@ -90,14 +93,29 @@
*/
private GlyphChecker mGlyphChecker = new GlyphChecker();
+ /**
+ * @see EmojiCompat.Config#setUseEmojiAsDefaultStyle(boolean)
+ */
+ private final boolean mUseEmojiAsDefaultStyle;
+
+ /**
+ * @see EmojiCompat.Config#setUseEmojiAsDefaultStyle(boolean, List)
+ */
+ private final int[] mEmojiAsDefaultStyleExceptions;
+
EmojiProcessor(@NonNull final MetadataRepo metadataRepo,
- @NonNull final EmojiCompat.SpanFactory spanFactory) {
+ @NonNull final EmojiCompat.SpanFactory spanFactory,
+ final boolean useEmojiAsDefaultStyle,
+ @Nullable final int[] emojiAsDefaultStyleExceptions) {
mSpanFactory = spanFactory;
mMetadataRepo = metadataRepo;
+ mUseEmojiAsDefaultStyle = useEmojiAsDefaultStyle;
+ mEmojiAsDefaultStyleExceptions = emojiAsDefaultStyleExceptions;
}
EmojiMetadata getEmojiMetadata(@NonNull final CharSequence charSequence) {
- final ProcessorSm sm = new ProcessorSm(mMetadataRepo.getRootNode());
+ final ProcessorSm sm = new ProcessorSm(mMetadataRepo.getRootNode(),
+ mUseEmojiAsDefaultStyle, mEmojiAsDefaultStyleExceptions);
final int end = charSequence.length();
int currentOffset = 0;
@@ -189,7 +207,8 @@
}
// add new ones
int addedCount = 0;
- final ProcessorSm sm = new ProcessorSm(mMetadataRepo.getRootNode());
+ final ProcessorSm sm = new ProcessorSm(mMetadataRepo.getRootNode(),
+ mUseEmojiAsDefaultStyle, mEmojiAsDefaultStyleExceptions);
int currentOffset = start;
int codePoint = Character.codePointAt(charSequence, currentOffset);
@@ -483,9 +502,22 @@
*/
private int mCurrentDepth;
- ProcessorSm(MetadataRepo.Node rootNode) {
+ /**
+ * @see EmojiCompat.Config#setUseEmojiAsDefaultStyle(boolean)
+ */
+ private final boolean mUseEmojiAsDefaultStyle;
+
+ /**
+ * @see EmojiCompat.Config#setUseEmojiAsDefaultStyle(boolean, List)
+ */
+ private final int[] mEmojiAsDefaultStyleExceptions;
+
+ ProcessorSm(MetadataRepo.Node rootNode, boolean useEmojiAsDefaultStyle,
+ int[] emojiAsDefaultStyleExceptions) {
mRootNode = rootNode;
mCurrentNode = rootNode;
+ mUseEmojiAsDefaultStyle = useEmojiAsDefaultStyle;
+ mEmojiAsDefaultStyleExceptions = emojiAsDefaultStyleExceptions;
}
@Action
@@ -505,8 +537,7 @@
action = ACTION_ADVANCE_END;
} else if (mCurrentNode.getData() != null) {
if (mCurrentDepth == 1) {
- if (mCurrentNode.getData().isDefaultEmoji()
- || isEmojiStyle(mLastCodepoint)) {
+ if (shouldUseEmojiPresentationStyleForSingleCodepoint()) {
mFlushNode = mCurrentNode;
action = ACTION_FLUSH;
reset();
@@ -571,9 +602,32 @@
*/
boolean isInFlushableState() {
return mState == STATE_WALKING && mCurrentNode.getData() != null
- && (mCurrentNode.getData().isDefaultEmoji()
- || isEmojiStyle(mLastCodepoint)
- || mCurrentDepth > 1);
+ && (mCurrentDepth > 1 || shouldUseEmojiPresentationStyleForSingleCodepoint());
+ }
+
+ private boolean shouldUseEmojiPresentationStyleForSingleCodepoint() {
+ if (mCurrentNode.getData().isDefaultEmoji()) {
+ // The codepoint is emoji style by default.
+ return true;
+ }
+ if (isEmojiStyle(mLastCodepoint)) {
+ // The codepoint was followed by the emoji style variation selector.
+ return true;
+ }
+ if (mUseEmojiAsDefaultStyle) {
+ // Emoji presentation style for text style default emojis is enabled. We have
+ // to check that the current codepoint is not an exception.
+ if (mEmojiAsDefaultStyleExceptions == null) {
+ return true;
+ }
+ final int codepoint = mCurrentNode.getData().getCodepointAt(0);
+ final int index = Arrays.binarySearch(mEmojiAsDefaultStyleExceptions, codepoint);
+ if (index < 0) {
+ // Index is negative, so the codepoint was not found in the array of exceptions.
+ return true;
+ }
+ }
+ return false;
}
/**
diff --git a/emoji/core/tests/java/android/support/text/emoji/EmojiCompatTest.java b/emoji/core/tests/java/android/support/text/emoji/EmojiCompatTest.java
index 0ce26e4..724f8a0 100644
--- a/emoji/core/tests/java/android/support/text/emoji/EmojiCompatTest.java
+++ b/emoji/core/tests/java/android/support/text/emoji/EmojiCompatTest.java
@@ -87,8 +87,10 @@
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
+import java.util.List;
import java.util.Set;
@SmallTest
@@ -729,6 +731,58 @@
assertFalse(EmojiCompat.handleOnKeyDown(editable, event.getKeyCode(), event));
}
+ @Test
+ @SdkSuppress(minSdkVersion = 19)
+ public void testUseEmojiAsDefaultStyle_whenEmojiInTheMiddle() {
+ final Config config = new TestConfig().setReplaceAll(true);
+ EmojiCompat.reset(config);
+ String s = new TestString(0x0061, CHAR_DEFAULT_TEXT_STYLE, 0x0062).toString();
+ // no span should be added as the emoji is text style presented by default
+ assertThat(EmojiCompat.get().process(s), not(hasEmoji()));
+ // a span should be added when we use the emoji style presentation as default
+ EmojiCompat.reset(config.setUseEmojiAsDefaultStyle(true));
+ assertThat(EmojiCompat.get().process(s), hasEmojiAt(DEFAULT_TEXT_STYLE, 1, 2));
+ }
+
+ @Test
+ @SdkSuppress(minSdkVersion = 19)
+ public void testUseEmojiAsDefaultStyle_whenEmojiAtTheEnd() {
+ final Config config = new TestConfig().setReplaceAll(true);
+ EmojiCompat.reset(config);
+ String s = new TestString(0x0061, CHAR_DEFAULT_TEXT_STYLE).toString();
+ // no span should be added as the emoji is text style presented by default
+ assertThat(EmojiCompat.get().process(s), not(hasEmoji()));
+ // a span should be added when we use the emoji style presentation as default
+ EmojiCompat.reset(config.setUseEmojiAsDefaultStyle(true));
+ assertThat(EmojiCompat.get().process(s), hasEmojiAt(DEFAULT_TEXT_STYLE, 1, 2));
+ }
+
+ @Test
+ @SdkSuppress(minSdkVersion = 19)
+ public void testUseEmojiAsDefaultStyle_noEmojisAdded_whenMarkedAsException() {
+ final String s = new TestString(CHAR_DEFAULT_TEXT_STYLE).toString();
+ final List<Integer> exceptions =
+ Arrays.asList(CHAR_DEFAULT_TEXT_STYLE + 1, CHAR_DEFAULT_TEXT_STYLE);
+ final Config config = new TestConfig().setReplaceAll(true)
+ .setUseEmojiAsDefaultStyle(true, exceptions);
+ EmojiCompat.reset(config);
+ // no span should be added as the text style codepoint is marked as exception
+ assertThat(EmojiCompat.get().process(s), not(hasEmoji()));
+ }
+
+ @Test
+ @SdkSuppress(minSdkVersion = 19)
+ public void testUseEmojiAsDefaultStyle_emojisAdded_whenNotMarkedAsException() {
+ final String s = new TestString(CHAR_DEFAULT_TEXT_STYLE).toString();
+ final List<Integer> exceptions =
+ Arrays.asList(CHAR_DEFAULT_TEXT_STYLE - 1, CHAR_DEFAULT_TEXT_STYLE + 1);
+ final Config config = new TestConfig().setReplaceAll(true)
+ .setUseEmojiAsDefaultStyle(true, exceptions);
+ EmojiCompat.reset(config);
+ // a span should be added as the codepoint is not included in the set of exceptions
+ assertThat(EmojiCompat.get().process(s), hasEmojiAt(DEFAULT_TEXT_STYLE, 0, 1));
+ }
+
private void assertCodePointMatch(EmojiMapping emoji) {
assertCodePointMatch(emoji.id(), emoji.codepoints());
}
diff --git a/room/common/src/main/java/android/arch/persistence/room/Database.java b/room/common/src/main/java/android/arch/persistence/room/Database.java
index f12d1b9..14e722f 100644
--- a/room/common/src/main/java/android/arch/persistence/room/Database.java
+++ b/room/common/src/main/java/android/arch/persistence/room/Database.java
@@ -34,7 +34,7 @@
* <pre>
* // User and Book are classes annotated with {@literal @}Entity.
* {@literal @}Database(version = 1, entities = {User.class, Book.class})
- * abstract class AppDatabase extends RoomDatabase() {
+ * abstract class AppDatabase extends RoomDatabase {
* // BookDao is a class annotated with {@literal @}Dao.
* abstract public BookDao bookDao();
* // UserDao is a class annotated with {@literal @}Dao.
diff --git a/samples/SupportCarDemos/OWNERS b/samples/SupportCarDemos/OWNERS
new file mode 100644
index 0000000..42ef8d4
--- /dev/null
+++ b/samples/SupportCarDemos/OWNERS
@@ -0,0 +1,2 @@
+ajchen@google.com
+yaoyx@google.com
\ No newline at end of file
diff --git a/v7/appcompat/res/values-bs/strings.xml b/v7/appcompat/res/values-bs/strings.xml
index 3687875..07d1411 100644
--- a/v7/appcompat/res/values-bs/strings.xml
+++ b/v7/appcompat/res/values-bs/strings.xml
@@ -29,8 +29,8 @@
<string name="abc_searchview_description_voice" msgid="893419373245838918">"Glasovno pretraživanje"</string>
<string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"Odaberite aplikaciju"</string>
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Prikaži sve"</string>
- <string name="abc_shareactionprovider_share_with_application" msgid="3300176832234831527">"Podijeli koristeći aplikaciju <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
- <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Podijeli sa"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="3300176832234831527">"Dijeli koristeći aplikaciju <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Dijeli sa"</string>
<string name="abc_capital_on" msgid="3405795526292276155">"UKLJUČI"</string>
<string name="abc_capital_off" msgid="121134116657445385">"ISKLJUČI"</string>
<string name="search_menu_title" msgid="146198913615257606">"Pretraži"</string>