Merge "Added descriptions for and renamed fields and methods related to deferring or ignoring nested calls to requestLayout. I personally found that the names and lack of descriptions made it hard to follow the logic and meaning of the code." into oc-mr1-jetpack-dev
diff --git a/leanback/src/android/support/v17/leanback/widget/GridLayoutManager.java b/leanback/src/android/support/v17/leanback/widget/GridLayoutManager.java
index 9d159ec..613198f 100644
--- a/leanback/src/android/support/v17/leanback/widget/GridLayoutManager.java
+++ b/leanback/src/android/support/v17/leanback/widget/GridLayoutManager.java
@@ -22,6 +22,7 @@
import android.content.Context;
import android.graphics.PointF;
import android.graphics.Rect;
+import android.os.Build;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
@@ -3655,7 +3656,32 @@
public boolean performAccessibilityAction(Recycler recycler, State state, int action,
Bundle args) {
saveContext(recycler, state);
- switch (action) {
+ int translatedAction = action;
+ boolean reverseFlowPrimary = (mFlag & PF_REVERSE_FLOW_PRIMARY) != 0;
+ if (Build.VERSION.SDK_INT >= 23) {
+ if (mOrientation == HORIZONTAL) {
+ if (action == AccessibilityNodeInfoCompat.AccessibilityActionCompat
+ .ACTION_SCROLL_LEFT.getId()) {
+ translatedAction = reverseFlowPrimary
+ ? AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD :
+ AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD;
+ } else if (action == AccessibilityNodeInfoCompat.AccessibilityActionCompat
+ .ACTION_SCROLL_RIGHT.getId()) {
+ translatedAction = reverseFlowPrimary
+ ? AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD :
+ AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD;
+ }
+ } else { // VERTICAL layout
+ if (action == AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SCROLL_UP
+ .getId()) {
+ translatedAction = AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD;
+ } else if (action == AccessibilityNodeInfoCompat.AccessibilityActionCompat
+ .ACTION_SCROLL_DOWN.getId()) {
+ translatedAction = AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD;
+ }
+ }
+ }
+ switch (translatedAction) {
case AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD:
processSelectionMoves(false, -1);
break;
@@ -3726,12 +3752,39 @@
AccessibilityNodeInfoCompat info) {
saveContext(recycler, state);
int count = state.getItemCount();
- if ((mFlag & PF_SCROLL_ENABLED) != 0 && count > 1 && !isItemFullyVisible(0)) {
- info.addAction(AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD);
+ boolean reverseFlowPrimary = (mFlag & PF_REVERSE_FLOW_PRIMARY) != 0;
+ if (count > 1 && !isItemFullyVisible(0)) {
+ if (Build.VERSION.SDK_INT >= 23) {
+ if (mOrientation == HORIZONTAL) {
+ info.addAction(reverseFlowPrimary
+ ? AccessibilityNodeInfoCompat.AccessibilityActionCompat
+ .ACTION_SCROLL_RIGHT :
+ AccessibilityNodeInfoCompat.AccessibilityActionCompat
+ .ACTION_SCROLL_LEFT);
+ } else {
+ info.addAction(
+ AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SCROLL_UP);
+ }
+ } else {
+ info.addAction(AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD);
+ }
info.setScrollable(true);
}
- if ((mFlag & PF_SCROLL_ENABLED) != 0 && count > 1 && !isItemFullyVisible(count - 1)) {
- info.addAction(AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD);
+ if (count > 1 && !isItemFullyVisible(count - 1)) {
+ if (Build.VERSION.SDK_INT >= 23) {
+ if (mOrientation == HORIZONTAL) {
+ info.addAction(reverseFlowPrimary
+ ? AccessibilityNodeInfoCompat.AccessibilityActionCompat
+ .ACTION_SCROLL_LEFT :
+ AccessibilityNodeInfoCompat.AccessibilityActionCompat
+ .ACTION_SCROLL_RIGHT);
+ } else {
+ info.addAction(AccessibilityNodeInfoCompat.AccessibilityActionCompat
+ .ACTION_SCROLL_DOWN);
+ }
+ } else {
+ info.addAction(AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD);
+ }
info.setScrollable(true);
}
final AccessibilityNodeInfoCompat.CollectionInfoCompat collectionInfo =
diff --git a/leanback/tests/java/android/support/v17/leanback/widget/GridWidgetTest.java b/leanback/tests/java/android/support/v17/leanback/widget/GridWidgetTest.java
index 7bf96a5..4548494 100644
--- a/leanback/tests/java/android/support/v17/leanback/widget/GridWidgetTest.java
+++ b/leanback/tests/java/android/support/v17/leanback/widget/GridWidgetTest.java
@@ -4312,6 +4312,252 @@
waitForScrollIdle(mVerifyLayout);
assertEquals(1, mGridView.getSelectedPosition());
}
+ @Test
+ public void testAccessibilityRespondToLeftRight() throws Throwable {
+ Intent intent = new Intent();
+ intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID, R.layout.horizontal_linear);
+ intent.putExtra(GridActivity.EXTRA_CHILD_LAYOUT_ID, R.layout.item_button_at_bottom);
+ intent.putExtra(GridActivity.EXTRA_ITEMS, new int[]{});
+ intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
+ initActivity(intent);
+ mOrientation = BaseGridView.HORIZONTAL;
+ mNumRows = 1;
+
+ int width = mGridView.getWidth() - mGridView.getPaddingLeft()
+ - mGridView.getPaddingRight();
+ final int childWidth = width - mGridView.getHorizontalSpacing() - 500;
+ mActivityTestRule.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mGridView.setWindowAlignment(BaseGridView.WINDOW_ALIGN_NO_EDGE);
+ mGridView.setWindowAlignmentOffset(100);
+ mGridView.setWindowAlignmentOffsetPercent(BaseGridView
+ .WINDOW_ALIGN_OFFSET_PERCENT_DISABLED);
+ mGridView.setItemAlignmentOffset(0);
+ mGridView.setItemAlignmentOffsetPercent(BaseGridView
+ .ITEM_ALIGN_OFFSET_PERCENT_DISABLED);
+ }
+ });
+ mActivity.addItems(0, new int[]{childWidth, childWidth});
+ waitForItemAnimation();
+ setSelectedPosition(1);
+ final RecyclerViewAccessibilityDelegate delegateCompat = mGridView
+ .getCompatAccessibilityDelegate();
+ final AccessibilityNodeInfoCompat info = AccessibilityNodeInfoCompat.obtain();
+ mActivityTestRule.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ delegateCompat.onInitializeAccessibilityNodeInfo(mGridView, info);
+ }
+ });
+ assertTrue("test sanity", info.isScrollable());
+ if (Build.VERSION.SDK_INT >= 23) {
+ assertTrue("test sanity", info.removeAction(AccessibilityNodeInfoCompat
+ .AccessibilityActionCompat.ACTION_SCROLL_LEFT));
+ } else {
+ assertTrue("test sanity", info.removeAction(AccessibilityNodeInfoCompat
+ .AccessibilityActionCompat.ACTION_SCROLL_BACKWARD));
+ }
+
+ mActivityTestRule.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ if (Build.VERSION.SDK_INT >= 23) {
+ delegateCompat.performAccessibilityAction(mGridView, AccessibilityNodeInfoCompat
+ .AccessibilityActionCompat.ACTION_SCROLL_LEFT.getId(), null);
+ } else {
+ delegateCompat.performAccessibilityAction(mGridView, AccessibilityNodeInfoCompat
+ .ACTION_SCROLL_BACKWARD, null);
+ }
+ }
+ });
+ waitForScrollIdle(mVerifyLayout);
+ assertEquals(0, mGridView.getSelectedPosition());
+ setSelectedPosition(0);
+ mActivityTestRule.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ delegateCompat.onInitializeAccessibilityNodeInfo(mGridView, info);
+ }
+ });
+ if (Build.VERSION.SDK_INT >= 23) {
+ assertTrue("test sanity", info.removeAction(AccessibilityNodeInfoCompat
+ .AccessibilityActionCompat.ACTION_SCROLL_RIGHT));
+ } else {
+ assertTrue("test sanity", info.removeAction(AccessibilityNodeInfoCompat
+ .AccessibilityActionCompat.ACTION_SCROLL_FORWARD));
+ }
+ mActivityTestRule.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ if (Build.VERSION.SDK_INT >= 23) {
+ delegateCompat.performAccessibilityAction(mGridView, AccessibilityNodeInfoCompat
+ .AccessibilityActionCompat.ACTION_SCROLL_RIGHT.getId(), null);
+ } else {
+ delegateCompat.performAccessibilityAction(mGridView, AccessibilityNodeInfoCompat
+ .ACTION_SCROLL_FORWARD, null);
+ }
+ }
+ });
+ waitForScrollIdle(mVerifyLayout);
+ assertEquals(1, mGridView.getSelectedPosition());
+ }
+
+ @Test
+ public void testAccessibilityRespondToLeftRightRtl() throws Throwable {
+ Intent intent = new Intent();
+ intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID, R.layout.horizontal_linear_rtl);
+ intent.putExtra(GridActivity.EXTRA_CHILD_LAYOUT_ID, R.layout.item_button_at_bottom);
+ intent.putExtra(GridActivity.EXTRA_ITEMS, new int[]{});
+ intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
+ initActivity(intent);
+ mOrientation = BaseGridView.HORIZONTAL;
+ mNumRows = 1;
+
+ int width = mGridView.getWidth() - mGridView.getPaddingLeft()
+ - mGridView.getPaddingRight();
+ final int childWidth = width - mGridView.getHorizontalSpacing() - 500;
+ mActivityTestRule.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mGridView.setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
+ mGridView.setWindowAlignment(BaseGridView.WINDOW_ALIGN_NO_EDGE);
+ mGridView.setWindowAlignmentOffset(100);
+ mGridView.setWindowAlignmentOffsetPercent(BaseGridView
+ .WINDOW_ALIGN_OFFSET_PERCENT_DISABLED);
+ mGridView.setItemAlignmentOffset(0);
+ mGridView.setItemAlignmentOffsetPercent(BaseGridView
+ .ITEM_ALIGN_OFFSET_PERCENT_DISABLED);
+ }
+ });
+ mActivity.addItems(0, new int[]{childWidth, childWidth});
+ waitForItemAnimation();
+ setSelectedPosition(1);
+ final RecyclerViewAccessibilityDelegate delegateCompat = mGridView
+ .getCompatAccessibilityDelegate();
+ final AccessibilityNodeInfoCompat info = AccessibilityNodeInfoCompat.obtain();
+ mActivityTestRule.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ delegateCompat.onInitializeAccessibilityNodeInfo(mGridView, info);
+ }
+ });
+ assertTrue("test sanity", info.isScrollable());
+ if (Build.VERSION.SDK_INT >= 23) {
+ assertTrue("test sanity", info.removeAction(AccessibilityNodeInfoCompat
+ .AccessibilityActionCompat.ACTION_SCROLL_RIGHT));
+ } else {
+ assertTrue("test sanity", info.removeAction(AccessibilityNodeInfoCompat
+ .AccessibilityActionCompat.ACTION_SCROLL_BACKWARD));
+ }
+
+ mActivityTestRule.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ if (Build.VERSION.SDK_INT >= 23) {
+ delegateCompat.performAccessibilityAction(mGridView, AccessibilityNodeInfoCompat
+ .AccessibilityActionCompat.ACTION_SCROLL_RIGHT.getId(), null);
+ } else {
+ delegateCompat.performAccessibilityAction(mGridView, AccessibilityNodeInfoCompat
+ .ACTION_SCROLL_BACKWARD, null);
+ }
+ }
+ });
+ waitForScrollIdle(mVerifyLayout);
+ assertEquals(0, mGridView.getSelectedPosition());
+ setSelectedPosition(0);
+ mActivityTestRule.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ delegateCompat.onInitializeAccessibilityNodeInfo(mGridView, info);
+ }
+ });
+ if (Build.VERSION.SDK_INT >= 23) {
+ assertTrue("test sanity", info.removeAction(AccessibilityNodeInfoCompat
+ .AccessibilityActionCompat.ACTION_SCROLL_LEFT));
+ } else {
+ assertTrue("test sanity", info.removeAction(AccessibilityNodeInfoCompat
+ .AccessibilityActionCompat.ACTION_SCROLL_FORWARD));
+ }
+ mActivityTestRule.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ if (Build.VERSION.SDK_INT >= 23) {
+ delegateCompat.performAccessibilityAction(mGridView, AccessibilityNodeInfoCompat
+ .AccessibilityActionCompat.ACTION_SCROLL_LEFT.getId(), null);
+ } else {
+ delegateCompat.performAccessibilityAction(mGridView, AccessibilityNodeInfoCompat
+ .ACTION_SCROLL_FORWARD, null);
+ }
+ }
+ });
+ waitForScrollIdle(mVerifyLayout);
+ assertEquals(1, mGridView.getSelectedPosition());
+ }
+
+ @Test
+ public void testAccessibilityRespondToScrollUpAction() throws Throwable {
+ Intent intent = new Intent();
+ intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID, R.layout.vertical_linear);
+ intent.putExtra(GridActivity.EXTRA_CHILD_LAYOUT_ID, R.layout.item_button_at_bottom);
+ intent.putExtra(GridActivity.EXTRA_ITEMS, new int[]{});
+ intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
+ initActivity(intent);
+ mOrientation = BaseGridView.VERTICAL;
+ mNumRows = 1;
+
+ int height = mGridView.getHeight() - mGridView.getPaddingTop()
+ - mGridView.getPaddingBottom();
+ final int childHeight = height - mGridView.getVerticalSpacing() - 100;
+ mActivityTestRule.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mGridView.setWindowAlignment(BaseGridView.WINDOW_ALIGN_NO_EDGE);
+ mGridView.setWindowAlignmentOffset(100);
+ mGridView.setWindowAlignmentOffsetPercent(BaseGridView
+ .WINDOW_ALIGN_OFFSET_PERCENT_DISABLED);
+ mGridView.setItemAlignmentOffset(0);
+ mGridView.setItemAlignmentOffsetPercent(BaseGridView
+ .ITEM_ALIGN_OFFSET_PERCENT_DISABLED);
+ }
+ });
+ mActivity.addItems(0, new int[]{childHeight, childHeight});
+ waitForItemAnimation();
+ setSelectedPosition(1);
+
+ final RecyclerViewAccessibilityDelegate delegateCompat = mGridView
+ .getCompatAccessibilityDelegate();
+ final AccessibilityNodeInfoCompat info = AccessibilityNodeInfoCompat.obtain();
+ mActivityTestRule.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ delegateCompat.onInitializeAccessibilityNodeInfo(mGridView, info);
+ }
+ });
+ assertTrue("test sanity", info.isScrollable());
+ if (Build.VERSION.SDK_INT >= 23) {
+ assertTrue("test sanity", info.removeAction(AccessibilityNodeInfoCompat
+ .AccessibilityActionCompat.ACTION_SCROLL_UP));
+ } else {
+ assertTrue("test sanity", info.removeAction(AccessibilityNodeInfoCompat
+ .AccessibilityActionCompat.ACTION_SCROLL_BACKWARD));
+ }
+
+ mActivityTestRule.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ if (Build.VERSION.SDK_INT >= 23) {
+ delegateCompat.performAccessibilityAction(mGridView, AccessibilityNodeInfoCompat
+ .AccessibilityActionCompat.ACTION_SCROLL_UP.getId(), null);
+ } else {
+ delegateCompat.performAccessibilityAction(mGridView, AccessibilityNodeInfoCompat
+ .ACTION_SCROLL_BACKWARD, null);
+ }
+ }
+ });
+ waitForScrollIdle(mVerifyLayout);
+ assertEquals(0, mGridView.getSelectedPosition());
+ }
@Test
public void testAccessibilityScrollBackwardHalfVisible() throws Throwable {
diff --git a/room/compiler/src/test/kotlin/android/arch/persistence/room/processor/PojoProcessorTest.kt b/room/compiler/src/test/kotlin/android/arch/persistence/room/processor/PojoProcessorTest.kt
index bf34b4c..97cfe74 100644
--- a/room/compiler/src/test/kotlin/android/arch/persistence/room/processor/PojoProcessorTest.kt
+++ b/room/compiler/src/test/kotlin/android/arch/persistence/room/processor/PojoProcessorTest.kt
@@ -552,7 +552,7 @@
}
@Test
- fun constructor_ambiguous_twoFieldsExcatMatch() {
+ fun constructor_ambiguous_twoFieldsExactMatch() {
val pojoCode = """
public String mName;
public String _name;
@@ -708,6 +708,18 @@
ProcessorErrors.TOO_MANY_POJO_CONSTRUCTORS_CHOOSING_NO_ARG)
}
+ @Test // added for b/69562125
+ fun constructor_withNullabilityAnnotation() {
+ singleRun("""
+ String mName;
+ public MyPojo(@android.support.annotation.NonNull String name) {}
+ """) { pojo ->
+ val constructor = pojo.constructor
+ assertThat(constructor, notNullValue())
+ assertThat(constructor!!.params.size, `is`(1))
+ }.compilesWithoutError()
+ }
+
@Test
fun recursion_1Level() {
singleRun(
diff --git a/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/test/ConstructorTest.java b/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/test/ConstructorTest.java
index 7a21d98..46c875c 100644
--- a/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/test/ConstructorTest.java
+++ b/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/test/ConstructorTest.java
@@ -28,6 +28,8 @@
import android.arch.persistence.room.Query;
import android.arch.persistence.room.Room;
import android.arch.persistence.room.RoomDatabase;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
@@ -40,7 +42,8 @@
@SuppressWarnings("SqlNoDataSourceInspection")
@SmallTest
public class ConstructorTest {
- @Database(version = 1, entities = {FullConstructor.class, PartialConstructor.class},
+ @Database(version = 1, entities = {FullConstructor.class, PartialConstructor.class,
+ EntityWithAnnotations.class},
exportSchema = false)
abstract static class MyDb extends RoomDatabase {
abstract MyDao dao();
@@ -59,6 +62,12 @@
@Query("SELECT * FROM pc WHERE a = :a")
PartialConstructor loadPartial(int a);
+
+ @Insert
+ void insertEntityWithAnnotations(EntityWithAnnotations... items);
+
+ @Query("SELECT * FROM EntityWithAnnotations")
+ EntityWithAnnotations getEntitiWithAnnotations();
}
@SuppressWarnings("WeakerAccess")
@@ -167,6 +176,50 @@
}
}
+ @SuppressWarnings("WeakerAccess")
+ @Entity
+ static class EntityWithAnnotations {
+ @PrimaryKey
+ @NonNull
+ public final String id;
+
+ @NonNull
+ public final String username;
+
+ @Nullable
+ public final String displayName;
+
+ EntityWithAnnotations(
+ @NonNull String id,
+ @NonNull String username,
+ @Nullable String displayName) {
+ this.id = id;
+ this.username = username;
+ this.displayName = displayName;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ EntityWithAnnotations that = (EntityWithAnnotations) o;
+
+ if (!id.equals(that.id)) return false;
+ if (!username.equals(that.username)) return false;
+ return displayName != null ? displayName.equals(that.displayName)
+ : that.displayName == null;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = id.hashCode();
+ result = 31 * result + username.hashCode();
+ result = 31 * result + (displayName != null ? displayName.hashCode() : 0);
+ return result;
+ }
+ }
+
private MyDb mDb;
private MyDao mDao;
@@ -193,4 +246,11 @@
PartialConstructor load = mDao.loadPartial(3);
assertThat(load, is(item));
}
+
+ @Test // for bug b/69562125
+ public void entityWithAnnotations() {
+ EntityWithAnnotations item = new EntityWithAnnotations("a", "b", null);
+ mDao.insertEntityWithAnnotations(item);
+ assertThat(mDao.getEntitiWithAnnotations(), is(item));
+ }
}