Merge "Fix accessibility action parceling" into pi-dev

This commit is contained in:
Phil Weaver
2018-03-08 01:49:43 +00:00
committed by Android (Google) Code Review
2 changed files with 51 additions and 14 deletions

View File

@@ -3333,7 +3333,7 @@ public class AccessibilityNodeInfo implements Parcelable {
final int actionCount = mActions.size(); final int actionCount = mActions.size();
int nonStandardActionCount = 0; int nonStandardActionCount = 0;
int defaultStandardActions = 0; long defaultStandardActions = 0;
for (int i = 0; i < actionCount; i++) { for (int i = 0; i < actionCount; i++) {
AccessibilityAction action = mActions.get(i); AccessibilityAction action = mActions.get(i);
if (isDefaultStandardAction(action)) { if (isDefaultStandardAction(action)) {
@@ -3342,7 +3342,7 @@ public class AccessibilityNodeInfo implements Parcelable {
nonStandardActionCount++; nonStandardActionCount++;
} }
} }
parcel.writeInt(defaultStandardActions); parcel.writeLong(defaultStandardActions);
parcel.writeInt(nonStandardActionCount); parcel.writeInt(nonStandardActionCount);
for (int i = 0; i < actionCount; i++) { for (int i = 0; i < actionCount; i++) {
@@ -3353,7 +3353,7 @@ public class AccessibilityNodeInfo implements Parcelable {
} }
} }
} else { } else {
parcel.writeInt(0); parcel.writeLong(0);
parcel.writeInt(0); parcel.writeInt(0);
} }
} }
@@ -3540,7 +3540,7 @@ public class AccessibilityNodeInfo implements Parcelable {
} }
if (isBitSet(nonDefaultFields, fieldIndex++)) { if (isBitSet(nonDefaultFields, fieldIndex++)) {
final int standardActions = parcel.readInt(); final long standardActions = parcel.readLong();
addStandardActions(standardActions); addStandardActions(standardActions);
final int nonStandardActionCount = parcel.readInt(); final int nonStandardActionCount = parcel.readInt();
for (int i = 0; i < nonStandardActionCount; i++) { for (int i = 0; i < nonStandardActionCount; i++) {
@@ -3621,7 +3621,7 @@ public class AccessibilityNodeInfo implements Parcelable {
} }
private static boolean isDefaultStandardAction(AccessibilityAction action) { private static boolean isDefaultStandardAction(AccessibilityAction action) {
return action.mSerializationFlag != -1 && TextUtils.isEmpty(action.getLabel()); return (action.mSerializationFlag != -1L) && TextUtils.isEmpty(action.getLabel());
} }
private static AccessibilityAction getActionSingleton(int actionId) { private static AccessibilityAction getActionSingleton(int actionId) {
@@ -3636,7 +3636,7 @@ public class AccessibilityNodeInfo implements Parcelable {
return null; return null;
} }
private static AccessibilityAction getActionSingletonBySerializationFlag(int flag) { private static AccessibilityAction getActionSingletonBySerializationFlag(long flag) {
final int actions = AccessibilityAction.sStandardActions.size(); final int actions = AccessibilityAction.sStandardActions.size();
for (int i = 0; i < actions; i++) { for (int i = 0; i < actions; i++) {
AccessibilityAction currentAction = AccessibilityAction.sStandardActions.valueAt(i); AccessibilityAction currentAction = AccessibilityAction.sStandardActions.valueAt(i);
@@ -3648,10 +3648,10 @@ public class AccessibilityNodeInfo implements Parcelable {
return null; return null;
} }
private void addStandardActions(int serializationIdMask) { private void addStandardActions(long serializationIdMask) {
int remainingIds = serializationIdMask; long remainingIds = serializationIdMask;
while (remainingIds > 0) { while (remainingIds > 0) {
final int id = 1 << Integer.numberOfTrailingZeros(remainingIds); final long id = 1L << Long.numberOfTrailingZeros(remainingIds);
remainingIds &= ~id; remainingIds &= ~id;
AccessibilityAction action = getActionSingletonBySerializationFlag(id); AccessibilityAction action = getActionSingletonBySerializationFlag(id);
addAction(action); addAction(action);
@@ -4276,7 +4276,7 @@ public class AccessibilityNodeInfo implements Parcelable {
private final CharSequence mLabel; private final CharSequence mLabel;
/** @hide */ /** @hide */
public int mSerializationFlag = -1; public long mSerializationFlag = -1L;
/** /**
* Creates a new AccessibilityAction. For adding a standard action without a specific label, * Creates a new AccessibilityAction. For adding a standard action without a specific label,
@@ -4310,7 +4310,7 @@ public class AccessibilityNodeInfo implements Parcelable {
private AccessibilityAction(int standardActionId) { private AccessibilityAction(int standardActionId) {
this(standardActionId, null); this(standardActionId, null);
mSerializationFlag = (int) bitAt(sStandardActions.size()); mSerializationFlag = bitAt(sStandardActions.size());
sStandardActions.add(this); sStandardActions.add(this);
} }

View File

@@ -16,8 +16,13 @@
package android.view.accessibility; package android.view.accessibility;
import static org.hamcrest.Matchers.emptyCollectionOf;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasItem;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
import android.os.Parcel;
import android.support.test.filters.LargeTest; import android.support.test.filters.LargeTest;
import android.support.test.runner.AndroidJUnit4; import android.support.test.runner.AndroidJUnit4;
import android.util.ArraySet; import android.util.ArraySet;
@@ -38,10 +43,10 @@ public class AccessibilityNodeInfoTest {
public void testStandardActions_serializationFlagIsValid() { public void testStandardActions_serializationFlagIsValid() {
AccessibilityAction brokenStandardAction = CollectionUtils.find( AccessibilityAction brokenStandardAction = CollectionUtils.find(
new ArrayList<>(AccessibilityAction.sStandardActions), new ArrayList<>(AccessibilityAction.sStandardActions),
action -> Integer.bitCount(action.mSerializationFlag) != 1); action -> Long.bitCount(action.mSerializationFlag) != 1);
if (brokenStandardAction != null) { if (brokenStandardAction != null) {
String message = "Invalid serialization flag(0x" String message = "Invalid serialization flag(0x"
+ Integer.toHexString(brokenStandardAction.mSerializationFlag) + Long.toHexString(brokenStandardAction.mSerializationFlag)
+ ") in " + brokenStandardAction; + ") in " + brokenStandardAction;
if (brokenStandardAction.mSerializationFlag == 0L) { if (brokenStandardAction.mSerializationFlag == 0L) {
message += "\nThis is likely due to an overflow"; message += "\nThis is likely due to an overflow";
@@ -56,7 +61,7 @@ public class AccessibilityNodeInfoTest {
&& action.getId() != action.mSerializationFlag); && action.getId() != action.mSerializationFlag);
if (brokenStandardAction != null) { if (brokenStandardAction != null) {
fail("Serialization flag(0x" fail("Serialization flag(0x"
+ Integer.toHexString(brokenStandardAction.mSerializationFlag) + Long.toHexString(brokenStandardAction.mSerializationFlag)
+ ") is different from legacy action id(0x" + ") is different from legacy action id(0x"
+ Integer.toHexString(brokenStandardAction.getId()) + Integer.toHexString(brokenStandardAction.getId())
+ ") in " + brokenStandardAction); + ") in " + brokenStandardAction);
@@ -77,4 +82,36 @@ public class AccessibilityNodeInfoTest {
} }
} }
@Test
public void testStandardActions_allComeThroughParceling() {
for (AccessibilityAction action : AccessibilityAction.sStandardActions) {
final AccessibilityNodeInfo nodeWithAction = AccessibilityNodeInfo.obtain();
nodeWithAction.addAction(action);
assertThat(nodeWithAction.getActionList(), hasItem(action));
final Parcel parcel = Parcel.obtain();
nodeWithAction.writeToParcel(parcel, 0);
parcel.setDataPosition(0);
final AccessibilityNodeInfo unparceledNode =
AccessibilityNodeInfo.CREATOR.createFromParcel(parcel);
assertThat(unparceledNode.getActionList(), hasItem(action));
}
}
@Test
public void testEmptyListOfActions_parcelsCorrectly() {
// Also set text, as if there's nothing else in the parcel it can unparcel even with
// a bug present.
final String text = "text";
final AccessibilityNodeInfo nodeWithEmptyActionList = AccessibilityNodeInfo.obtain();
nodeWithEmptyActionList.addAction(AccessibilityAction.ACTION_ACCESSIBILITY_FOCUS);
nodeWithEmptyActionList.removeAction(AccessibilityAction.ACTION_ACCESSIBILITY_FOCUS);
nodeWithEmptyActionList.setText(text);
final Parcel parcel = Parcel.obtain();
nodeWithEmptyActionList.writeToParcel(parcel, 0);
parcel.setDataPosition(0);
final AccessibilityNodeInfo unparceledNode =
AccessibilityNodeInfo.CREATOR.createFromParcel(parcel);
assertThat(unparceledNode.getActionList(), emptyCollectionOf(AccessibilityAction.class));
assertThat(unparceledNode.getText(), equalTo(text));
}
} }