Loading core/java/android/view/autofill/AutofillId.java +52 −20 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ */ package android.view.autofill; import android.annotation.NonNull; import android.annotation.TestApi; import android.os.Parcel; import android.os.Parcelable; Loading @@ -25,33 +26,47 @@ import android.view.View; */ public final class AutofillId implements Parcelable { /** @hide */ public static final int NO_SESSION = 0; private static final int FLAG_IS_VIRTUAL = 0x1; private static final int FLAG_HAS_SESSION = 0x2; private final int mViewId; private final boolean mVirtual; private final int mFlags; private final int mVirtualId; private final int mSessionId; /** @hide */ @TestApi public AutofillId(int id) { mVirtual = false; mViewId = id; mVirtualId = View.NO_ID; this(/* flags= */ 0, id, View.NO_ID, NO_SESSION); } /** @hide */ @TestApi public AutofillId(AutofillId parent, int virtualChildId) { mVirtual = true; mViewId = parent.mViewId; mVirtualId = virtualChildId; public AutofillId(@NonNull AutofillId parent, int virtualChildId) { this(FLAG_IS_VIRTUAL, parent.mViewId, virtualChildId, NO_SESSION); } /** @hide */ public AutofillId(int parentId, int virtualChildId) { mVirtual = true; this(FLAG_IS_VIRTUAL, parentId, virtualChildId, NO_SESSION); } /** @hide */ public AutofillId(@NonNull AutofillId parent, int virtualChildId, int sessionId) { this(FLAG_IS_VIRTUAL | FLAG_HAS_SESSION, parent.mViewId, virtualChildId, sessionId); } private AutofillId(int flags, int parentId, int virtualChildId, int sessionId) { mFlags = flags; mViewId = parentId; mVirtualId = virtualChildId; mSessionId = sessionId; } /** @hide */ public int getViewId() { return mViewId; Loading @@ -64,7 +79,16 @@ public final class AutofillId implements Parcelable { /** @hide */ public boolean isVirtual() { return mVirtual; return (mFlags & FLAG_IS_VIRTUAL) != 0; } private boolean hasSession() { return (mFlags & FLAG_HAS_SESSION) != 0; } /** @hide */ public int getSessionId() { return mSessionId; } ///////////////////////////////// Loading @@ -77,6 +101,7 @@ public final class AutofillId implements Parcelable { int result = 1; result = prime * result + mViewId; result = prime * result + mVirtualId; result = prime * result + mSessionId; return result; } Loading @@ -88,15 +113,19 @@ public final class AutofillId implements Parcelable { final AutofillId other = (AutofillId) obj; if (mViewId != other.mViewId) return false; if (mVirtualId != other.mVirtualId) return false; if (mSessionId != other.mSessionId) return false; return true; } @Override public String toString() { final StringBuilder builder = new StringBuilder().append(mViewId); if (mVirtual) { if (isVirtual()) { builder.append(':').append(mVirtualId); } if (hasSession()) { builder.append('@').append(mSessionId); } return builder.toString(); } Loading @@ -108,21 +137,24 @@ public final class AutofillId implements Parcelable { @Override public void writeToParcel(Parcel parcel, int flags) { parcel.writeInt(mViewId); parcel.writeInt(mVirtual ? 1 : 0); parcel.writeInt(mFlags); if (isVirtual()) { parcel.writeInt(mVirtualId); } private AutofillId(Parcel parcel) { mViewId = parcel.readInt(); mVirtual = parcel.readInt() == 1; mVirtualId = parcel.readInt(); if (hasSession()) { parcel.writeInt(mSessionId); } } public static final Parcelable.Creator<AutofillId> CREATOR = new Parcelable.Creator<AutofillId>() { @Override public AutofillId createFromParcel(Parcel source) { return new AutofillId(source); final int viewId = source.readInt(); final int flags = source.readInt(); final int virtualId = (flags & FLAG_IS_VIRTUAL) != 0 ? source.readInt() : View.NO_ID; final int sessionId = (flags & FLAG_HAS_SESSION) != 0 ? source.readInt() : NO_SESSION; return new AutofillId(flags, viewId, virtualId, sessionId); } @Override Loading core/java/android/view/contentcapture/ContentCaptureSession.java +18 −6 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import android.view.autofill.AutofillId; import android.view.contentcapture.ViewNode.ViewStructureImpl; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.Preconditions; import dalvik.system.CloseGuard; Loading Loading @@ -107,7 +108,7 @@ public abstract class ContentCaptureSession implements AutoCloseable { /** @hide */ @Nullable protected final String mId = UUID.randomUUID().toString(); protected final String mId; private int mState = STATE_UNKNOWN; Loading @@ -123,6 +124,13 @@ public abstract class ContentCaptureSession implements AutoCloseable { /** @hide */ protected ContentCaptureSession() { this(UUID.randomUUID().toString()); } /** @hide */ @VisibleForTesting public ContentCaptureSession(@NonNull String id) { mId = Preconditions.checkNotNull(id); mCloseGuard.open("destroy"); } Loading @@ -140,6 +148,13 @@ public abstract class ContentCaptureSession implements AutoCloseable { return mContentCaptureSessionId; } /** @hide */ @VisibleForTesting public int getIdAsInt() { // TODO(b/121197119): use sessionId instead of hashcode once it's changed to int return mId.hashCode(); } /** * Creates a new {@link ContentCaptureSession}. * Loading Loading @@ -315,9 +330,7 @@ public abstract class ContentCaptureSession implements AutoCloseable { public @NonNull AutofillId newAutofillId(@NonNull AutofillId parentId, int virtualChildId) { Preconditions.checkNotNull(parentId); Preconditions.checkArgument(!parentId.isVirtual(), "virtual ids cannot have children"); // TODO(b/121197119): we need to add the session id to the AutofillId to make them unique // per session return new AutofillId(parentId, virtualChildId); return new AutofillId(parentId, virtualChildId, getIdAsInt()); } /** Loading @@ -333,8 +346,7 @@ public abstract class ContentCaptureSession implements AutoCloseable { @NonNull public final ViewStructure newVirtualViewStructure(@NonNull AutofillId parentId, int virtualId) { // TODO(b/121197119): use the constructor that takes a session id / assert on unit test. return new ViewNode.ViewStructureImpl(parentId, virtualId); return new ViewNode.ViewStructureImpl(parentId, virtualId, getIdAsInt()); } boolean isContentCaptureEnabled() { Loading core/java/android/view/contentcapture/ViewNode.java +2 −2 Original line number Diff line number Diff line Loading @@ -672,9 +672,9 @@ public final class ViewNode extends AssistStructure.ViewNode { } @VisibleForTesting // Must be public to be accessed from FrameworkCoreTests' apk. public ViewStructureImpl(@NonNull AutofillId parentId, int virtualId) { public ViewStructureImpl(@NonNull AutofillId parentId, int virtualId, int sessionId) { mNode.mParentAutofillId = Preconditions.checkNotNull(parentId); mNode.mAutofillId = new AutofillId(parentId, virtualId); mNode.mAutofillId = new AutofillId(parentId, virtualId, sessionId); } @VisibleForTesting // Must be public to be accessed from FrameworkCoreTests' apk. Loading core/tests/coretests/src/android/view/autofill/AutofillIdTest.java 0 → 100644 +150 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.view.autofill; import static com.google.common.truth.Truth.assertThat; import static org.testng.Assert.assertThrows; import android.os.Parcel; import android.view.View; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @RunWith(JUnit4.class) public class AutofillIdTest { @Test public void testNonVirtual() { final AutofillId id = new AutofillId(42); assertThat(id.getViewId()).isEqualTo(42); assertThat(id.isVirtual()).isFalse(); assertThat(id.getVirtualChildId()).isEqualTo(View.NO_ID); final AutofillId clone = cloneThroughParcel(id); assertThat(clone.getViewId()).isEqualTo(42); assertThat(clone.isVirtual()).isFalse(); assertThat(clone.getVirtualChildId()).isEqualTo(View.NO_ID); } @Test public void testVirtual() { final AutofillId id = new AutofillId(42, 108); assertThat(id.getViewId()).isEqualTo(42); assertThat(id.isVirtual()).isTrue(); assertThat(id.getVirtualChildId()).isEqualTo(108); final AutofillId clone = cloneThroughParcel(id); assertThat(clone.getViewId()).isEqualTo(42); assertThat(clone.isVirtual()).isTrue(); assertThat(clone.getVirtualChildId()).isEqualTo(108); } @Test public void testVirtual_parentObjectConstructor() { assertThrows(NullPointerException.class, () -> new AutofillId(null, 108)); final AutofillId id = new AutofillId(new AutofillId(42), 108); assertThat(id.getViewId()).isEqualTo(42); assertThat(id.isVirtual()).isTrue(); assertThat(id.getVirtualChildId()).isEqualTo(108); final AutofillId clone = cloneThroughParcel(id); assertThat(clone.getViewId()).isEqualTo(42); assertThat(clone.isVirtual()).isTrue(); assertThat(clone.getVirtualChildId()).isEqualTo(108); } @Test public void testVirtual_withSession() { final AutofillId id = new AutofillId(new AutofillId(42), 108, 666); assertThat(id.getViewId()).isEqualTo(42); assertThat(id.isVirtual()).isTrue(); assertThat(id.getVirtualChildId()).isEqualTo(108); assertThat(id.getSessionId()).isEqualTo(666); final AutofillId clone = cloneThroughParcel(id); assertThat(clone.getViewId()).isEqualTo(42); assertThat(clone.isVirtual()).isTrue(); assertThat(clone.getVirtualChildId()).isEqualTo(108); assertThat(clone.getSessionId()).isEqualTo(666); } @Test public void testEqualsHashCode() { final AutofillId realId = new AutofillId(42); final AutofillId realIdSame = new AutofillId(42); assertThat(realId).isEqualTo(realIdSame); assertThat(realIdSame).isEqualTo(realId); assertThat(realId.hashCode()).isEqualTo(realIdSame.hashCode()); final AutofillId realIdDifferent = new AutofillId(108); assertThat(realId).isNotEqualTo(realIdDifferent); assertThat(realIdDifferent).isNotEqualTo(realId); final AutofillId virtualId = new AutofillId(42, 1); final AutofillId virtualIdSame = new AutofillId(42, 1); assertThat(virtualId).isEqualTo(virtualIdSame); assertThat(virtualIdSame).isEqualTo(virtualId); assertThat(virtualId.hashCode()).isEqualTo(virtualIdSame.hashCode()); assertThat(virtualId).isNotEqualTo(realId); assertThat(realId).isNotEqualTo(virtualId); final AutofillId virtualIdDifferentChild = new AutofillId(42, 2); assertThat(virtualIdDifferentChild).isNotEqualTo(virtualId); assertThat(virtualId).isNotEqualTo(virtualIdDifferentChild); assertThat(virtualIdDifferentChild).isNotEqualTo(realId); assertThat(realId).isNotEqualTo(virtualIdDifferentChild); final AutofillId virtualIdDifferentParent = new AutofillId(108, 1); assertThat(virtualIdDifferentParent).isNotEqualTo(virtualId); assertThat(virtualId).isNotEqualTo(virtualIdDifferentParent); assertThat(virtualIdDifferentParent).isNotEqualTo(virtualIdDifferentChild); assertThat(virtualIdDifferentChild).isNotEqualTo(virtualIdDifferentParent); final AutofillId virtualIdDifferentSession = new AutofillId(new AutofillId(42), 1, 108); assertThat(virtualIdDifferentSession).isNotEqualTo(virtualId); assertThat(virtualId).isNotEqualTo(virtualIdDifferentSession); assertThat(virtualIdDifferentSession).isNotEqualTo(realId); assertThat(realId).isNotEqualTo(virtualIdDifferentSession); final AutofillId sameVirtualIdDifferentSession = new AutofillId(new AutofillId(42), 1, 108); assertThat(sameVirtualIdDifferentSession).isEqualTo(virtualIdDifferentSession); assertThat(virtualIdDifferentSession).isEqualTo(sameVirtualIdDifferentSession); assertThat(sameVirtualIdDifferentSession.hashCode()) .isEqualTo(virtualIdDifferentSession.hashCode()); } private AutofillId cloneThroughParcel(AutofillId id) { Parcel parcel = Parcel.obtain(); try { // Write to parcel parcel.setDataPosition(0); // Sanity / paranoid check id.writeToParcel(parcel, 0); // Read from parcel parcel.setDataPosition(0); AutofillId clone = AutofillId.CREATOR.createFromParcel(parcel); assertThat(clone).isNotNull(); return clone; } finally { parcel.recycle(); } } } core/tests/coretests/src/android/view/contentcapture/ContentCaptureSessionTest.java +87 −14 Original line number Diff line number Diff line Loading @@ -19,11 +19,14 @@ import static com.google.common.truth.Truth.assertThat; import static org.testng.Assert.assertThrows; import android.view.View; import android.view.ViewStructure; import android.view.autofill.AutofillId; import android.view.contentcapture.ViewNode.ViewStructureImpl; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Spy; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; /** Loading @@ -35,34 +38,104 @@ import org.mockito.junit.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.class) public class ContentCaptureSessionTest { /** * Uses a spy as ContentCaptureSession is abstract but (so far) we're testing its concrete * methods. */ @Spy private ContentCaptureSession mMockSession; private ContentCaptureSession mSession1 = new MyContentCaptureSession("111"); private ContentCaptureSession mSession2 = new MyContentCaptureSession("2222"); @Mock private View mMockView; @Test public void testNewAutofillId_invalid() { assertThrows(NullPointerException.class, () -> mMockSession.newAutofillId(null, 42)); assertThrows(NullPointerException.class, () -> mSession1.newAutofillId(null, 42)); assertThrows(IllegalArgumentException.class, () -> mMockSession.newAutofillId(new AutofillId(42, 42), 42)); () -> mSession1.newAutofillId(new AutofillId(42, 42), 42)); } @Test public void testNewAutofillId_valid() { final AutofillId parentId = new AutofillId(42); final AutofillId childId = mMockSession.newAutofillId(parentId, 108); final AutofillId childId = mSession1.newAutofillId(parentId, 108); assertThat(childId.getViewId()).isEqualTo(42); assertThat(childId.getVirtualChildId()).isEqualTo(108); // TODO(b/121197119): assert session id assertThat(childId.getSessionId()).isEqualTo(mSession1.getIdAsInt()); } @Test public void testNewAutofillId_differentSessions() { assertThat(mSession1.getIdAsInt()).isNotSameAs(mSession2.getIdAsInt()); //sanity check final AutofillId parentId = new AutofillId(42); final AutofillId childId1 = mSession1.newAutofillId(parentId, 108); final AutofillId childId2 = mSession2.newAutofillId(parentId, 108); assertThat(childId1).isNotEqualTo(childId2); assertThat(childId2).isNotEqualTo(childId1); } @Test public void testNotifyXXX_null() { assertThrows(NullPointerException.class, () -> mMockSession.notifyViewAppeared(null)); assertThrows(NullPointerException.class, () -> mMockSession.notifyViewDisappeared(null)); assertThrows(NullPointerException.class, () -> mSession1.notifyViewAppeared(null)); assertThrows(NullPointerException.class, () -> mSession1.notifyViewDisappeared(null)); assertThrows(NullPointerException.class, () -> mMockSession.notifyViewTextChanged(null, "whatever", 0)); () -> mSession1.notifyViewTextChanged(null, "whatever", 0)); } @Test public void testNewViewStructure() { assertThat(mMockView.getAutofillId()).isNotNull(); // sanity check final ViewStructure structure = mSession1.newViewStructure(mMockView); assertThat(structure).isNotNull(); assertThat(structure.getAutofillId()).isEqualTo(mMockView.getAutofillId()); } @Test public void testNewVirtualViewStructure() { final AutofillId parentId = new AutofillId(42); final ViewStructure structure = mSession1.newVirtualViewStructure(parentId, 108); assertThat(structure).isNotNull(); final AutofillId childId = mSession1.newAutofillId(parentId, 108); assertThat(structure.getAutofillId()).isEqualTo(childId); } // Cannot use @Spy because we need to pass the session id on constructor private class MyContentCaptureSession extends ContentCaptureSession { private MyContentCaptureSession(String id) { super(id); } @Override MainContentCaptureSession getMainCaptureSession() { throw new UnsupportedOperationException("should not have been called"); } @Override ContentCaptureSession newChild(ContentCaptureContext context) { throw new UnsupportedOperationException("should not have been called"); } @Override void flush() { throw new UnsupportedOperationException("should not have been called"); } @Override void onDestroy() { throw new UnsupportedOperationException("should not have been called"); } @Override void internalNotifyViewAppeared(ViewStructureImpl node) { throw new UnsupportedOperationException("should not have been called"); } @Override void internalNotifyViewDisappeared(AutofillId id) { throw new UnsupportedOperationException("should not have been called"); } @Override void internalNotifyViewTextChanged(AutofillId id, CharSequence text, int flags) { throw new UnsupportedOperationException("should not have been called"); } } } Loading
core/java/android/view/autofill/AutofillId.java +52 −20 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ */ package android.view.autofill; import android.annotation.NonNull; import android.annotation.TestApi; import android.os.Parcel; import android.os.Parcelable; Loading @@ -25,33 +26,47 @@ import android.view.View; */ public final class AutofillId implements Parcelable { /** @hide */ public static final int NO_SESSION = 0; private static final int FLAG_IS_VIRTUAL = 0x1; private static final int FLAG_HAS_SESSION = 0x2; private final int mViewId; private final boolean mVirtual; private final int mFlags; private final int mVirtualId; private final int mSessionId; /** @hide */ @TestApi public AutofillId(int id) { mVirtual = false; mViewId = id; mVirtualId = View.NO_ID; this(/* flags= */ 0, id, View.NO_ID, NO_SESSION); } /** @hide */ @TestApi public AutofillId(AutofillId parent, int virtualChildId) { mVirtual = true; mViewId = parent.mViewId; mVirtualId = virtualChildId; public AutofillId(@NonNull AutofillId parent, int virtualChildId) { this(FLAG_IS_VIRTUAL, parent.mViewId, virtualChildId, NO_SESSION); } /** @hide */ public AutofillId(int parentId, int virtualChildId) { mVirtual = true; this(FLAG_IS_VIRTUAL, parentId, virtualChildId, NO_SESSION); } /** @hide */ public AutofillId(@NonNull AutofillId parent, int virtualChildId, int sessionId) { this(FLAG_IS_VIRTUAL | FLAG_HAS_SESSION, parent.mViewId, virtualChildId, sessionId); } private AutofillId(int flags, int parentId, int virtualChildId, int sessionId) { mFlags = flags; mViewId = parentId; mVirtualId = virtualChildId; mSessionId = sessionId; } /** @hide */ public int getViewId() { return mViewId; Loading @@ -64,7 +79,16 @@ public final class AutofillId implements Parcelable { /** @hide */ public boolean isVirtual() { return mVirtual; return (mFlags & FLAG_IS_VIRTUAL) != 0; } private boolean hasSession() { return (mFlags & FLAG_HAS_SESSION) != 0; } /** @hide */ public int getSessionId() { return mSessionId; } ///////////////////////////////// Loading @@ -77,6 +101,7 @@ public final class AutofillId implements Parcelable { int result = 1; result = prime * result + mViewId; result = prime * result + mVirtualId; result = prime * result + mSessionId; return result; } Loading @@ -88,15 +113,19 @@ public final class AutofillId implements Parcelable { final AutofillId other = (AutofillId) obj; if (mViewId != other.mViewId) return false; if (mVirtualId != other.mVirtualId) return false; if (mSessionId != other.mSessionId) return false; return true; } @Override public String toString() { final StringBuilder builder = new StringBuilder().append(mViewId); if (mVirtual) { if (isVirtual()) { builder.append(':').append(mVirtualId); } if (hasSession()) { builder.append('@').append(mSessionId); } return builder.toString(); } Loading @@ -108,21 +137,24 @@ public final class AutofillId implements Parcelable { @Override public void writeToParcel(Parcel parcel, int flags) { parcel.writeInt(mViewId); parcel.writeInt(mVirtual ? 1 : 0); parcel.writeInt(mFlags); if (isVirtual()) { parcel.writeInt(mVirtualId); } private AutofillId(Parcel parcel) { mViewId = parcel.readInt(); mVirtual = parcel.readInt() == 1; mVirtualId = parcel.readInt(); if (hasSession()) { parcel.writeInt(mSessionId); } } public static final Parcelable.Creator<AutofillId> CREATOR = new Parcelable.Creator<AutofillId>() { @Override public AutofillId createFromParcel(Parcel source) { return new AutofillId(source); final int viewId = source.readInt(); final int flags = source.readInt(); final int virtualId = (flags & FLAG_IS_VIRTUAL) != 0 ? source.readInt() : View.NO_ID; final int sessionId = (flags & FLAG_HAS_SESSION) != 0 ? source.readInt() : NO_SESSION; return new AutofillId(flags, viewId, virtualId, sessionId); } @Override Loading
core/java/android/view/contentcapture/ContentCaptureSession.java +18 −6 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import android.view.autofill.AutofillId; import android.view.contentcapture.ViewNode.ViewStructureImpl; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.Preconditions; import dalvik.system.CloseGuard; Loading Loading @@ -107,7 +108,7 @@ public abstract class ContentCaptureSession implements AutoCloseable { /** @hide */ @Nullable protected final String mId = UUID.randomUUID().toString(); protected final String mId; private int mState = STATE_UNKNOWN; Loading @@ -123,6 +124,13 @@ public abstract class ContentCaptureSession implements AutoCloseable { /** @hide */ protected ContentCaptureSession() { this(UUID.randomUUID().toString()); } /** @hide */ @VisibleForTesting public ContentCaptureSession(@NonNull String id) { mId = Preconditions.checkNotNull(id); mCloseGuard.open("destroy"); } Loading @@ -140,6 +148,13 @@ public abstract class ContentCaptureSession implements AutoCloseable { return mContentCaptureSessionId; } /** @hide */ @VisibleForTesting public int getIdAsInt() { // TODO(b/121197119): use sessionId instead of hashcode once it's changed to int return mId.hashCode(); } /** * Creates a new {@link ContentCaptureSession}. * Loading Loading @@ -315,9 +330,7 @@ public abstract class ContentCaptureSession implements AutoCloseable { public @NonNull AutofillId newAutofillId(@NonNull AutofillId parentId, int virtualChildId) { Preconditions.checkNotNull(parentId); Preconditions.checkArgument(!parentId.isVirtual(), "virtual ids cannot have children"); // TODO(b/121197119): we need to add the session id to the AutofillId to make them unique // per session return new AutofillId(parentId, virtualChildId); return new AutofillId(parentId, virtualChildId, getIdAsInt()); } /** Loading @@ -333,8 +346,7 @@ public abstract class ContentCaptureSession implements AutoCloseable { @NonNull public final ViewStructure newVirtualViewStructure(@NonNull AutofillId parentId, int virtualId) { // TODO(b/121197119): use the constructor that takes a session id / assert on unit test. return new ViewNode.ViewStructureImpl(parentId, virtualId); return new ViewNode.ViewStructureImpl(parentId, virtualId, getIdAsInt()); } boolean isContentCaptureEnabled() { Loading
core/java/android/view/contentcapture/ViewNode.java +2 −2 Original line number Diff line number Diff line Loading @@ -672,9 +672,9 @@ public final class ViewNode extends AssistStructure.ViewNode { } @VisibleForTesting // Must be public to be accessed from FrameworkCoreTests' apk. public ViewStructureImpl(@NonNull AutofillId parentId, int virtualId) { public ViewStructureImpl(@NonNull AutofillId parentId, int virtualId, int sessionId) { mNode.mParentAutofillId = Preconditions.checkNotNull(parentId); mNode.mAutofillId = new AutofillId(parentId, virtualId); mNode.mAutofillId = new AutofillId(parentId, virtualId, sessionId); } @VisibleForTesting // Must be public to be accessed from FrameworkCoreTests' apk. Loading
core/tests/coretests/src/android/view/autofill/AutofillIdTest.java 0 → 100644 +150 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.view.autofill; import static com.google.common.truth.Truth.assertThat; import static org.testng.Assert.assertThrows; import android.os.Parcel; import android.view.View; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @RunWith(JUnit4.class) public class AutofillIdTest { @Test public void testNonVirtual() { final AutofillId id = new AutofillId(42); assertThat(id.getViewId()).isEqualTo(42); assertThat(id.isVirtual()).isFalse(); assertThat(id.getVirtualChildId()).isEqualTo(View.NO_ID); final AutofillId clone = cloneThroughParcel(id); assertThat(clone.getViewId()).isEqualTo(42); assertThat(clone.isVirtual()).isFalse(); assertThat(clone.getVirtualChildId()).isEqualTo(View.NO_ID); } @Test public void testVirtual() { final AutofillId id = new AutofillId(42, 108); assertThat(id.getViewId()).isEqualTo(42); assertThat(id.isVirtual()).isTrue(); assertThat(id.getVirtualChildId()).isEqualTo(108); final AutofillId clone = cloneThroughParcel(id); assertThat(clone.getViewId()).isEqualTo(42); assertThat(clone.isVirtual()).isTrue(); assertThat(clone.getVirtualChildId()).isEqualTo(108); } @Test public void testVirtual_parentObjectConstructor() { assertThrows(NullPointerException.class, () -> new AutofillId(null, 108)); final AutofillId id = new AutofillId(new AutofillId(42), 108); assertThat(id.getViewId()).isEqualTo(42); assertThat(id.isVirtual()).isTrue(); assertThat(id.getVirtualChildId()).isEqualTo(108); final AutofillId clone = cloneThroughParcel(id); assertThat(clone.getViewId()).isEqualTo(42); assertThat(clone.isVirtual()).isTrue(); assertThat(clone.getVirtualChildId()).isEqualTo(108); } @Test public void testVirtual_withSession() { final AutofillId id = new AutofillId(new AutofillId(42), 108, 666); assertThat(id.getViewId()).isEqualTo(42); assertThat(id.isVirtual()).isTrue(); assertThat(id.getVirtualChildId()).isEqualTo(108); assertThat(id.getSessionId()).isEqualTo(666); final AutofillId clone = cloneThroughParcel(id); assertThat(clone.getViewId()).isEqualTo(42); assertThat(clone.isVirtual()).isTrue(); assertThat(clone.getVirtualChildId()).isEqualTo(108); assertThat(clone.getSessionId()).isEqualTo(666); } @Test public void testEqualsHashCode() { final AutofillId realId = new AutofillId(42); final AutofillId realIdSame = new AutofillId(42); assertThat(realId).isEqualTo(realIdSame); assertThat(realIdSame).isEqualTo(realId); assertThat(realId.hashCode()).isEqualTo(realIdSame.hashCode()); final AutofillId realIdDifferent = new AutofillId(108); assertThat(realId).isNotEqualTo(realIdDifferent); assertThat(realIdDifferent).isNotEqualTo(realId); final AutofillId virtualId = new AutofillId(42, 1); final AutofillId virtualIdSame = new AutofillId(42, 1); assertThat(virtualId).isEqualTo(virtualIdSame); assertThat(virtualIdSame).isEqualTo(virtualId); assertThat(virtualId.hashCode()).isEqualTo(virtualIdSame.hashCode()); assertThat(virtualId).isNotEqualTo(realId); assertThat(realId).isNotEqualTo(virtualId); final AutofillId virtualIdDifferentChild = new AutofillId(42, 2); assertThat(virtualIdDifferentChild).isNotEqualTo(virtualId); assertThat(virtualId).isNotEqualTo(virtualIdDifferentChild); assertThat(virtualIdDifferentChild).isNotEqualTo(realId); assertThat(realId).isNotEqualTo(virtualIdDifferentChild); final AutofillId virtualIdDifferentParent = new AutofillId(108, 1); assertThat(virtualIdDifferentParent).isNotEqualTo(virtualId); assertThat(virtualId).isNotEqualTo(virtualIdDifferentParent); assertThat(virtualIdDifferentParent).isNotEqualTo(virtualIdDifferentChild); assertThat(virtualIdDifferentChild).isNotEqualTo(virtualIdDifferentParent); final AutofillId virtualIdDifferentSession = new AutofillId(new AutofillId(42), 1, 108); assertThat(virtualIdDifferentSession).isNotEqualTo(virtualId); assertThat(virtualId).isNotEqualTo(virtualIdDifferentSession); assertThat(virtualIdDifferentSession).isNotEqualTo(realId); assertThat(realId).isNotEqualTo(virtualIdDifferentSession); final AutofillId sameVirtualIdDifferentSession = new AutofillId(new AutofillId(42), 1, 108); assertThat(sameVirtualIdDifferentSession).isEqualTo(virtualIdDifferentSession); assertThat(virtualIdDifferentSession).isEqualTo(sameVirtualIdDifferentSession); assertThat(sameVirtualIdDifferentSession.hashCode()) .isEqualTo(virtualIdDifferentSession.hashCode()); } private AutofillId cloneThroughParcel(AutofillId id) { Parcel parcel = Parcel.obtain(); try { // Write to parcel parcel.setDataPosition(0); // Sanity / paranoid check id.writeToParcel(parcel, 0); // Read from parcel parcel.setDataPosition(0); AutofillId clone = AutofillId.CREATOR.createFromParcel(parcel); assertThat(clone).isNotNull(); return clone; } finally { parcel.recycle(); } } }
core/tests/coretests/src/android/view/contentcapture/ContentCaptureSessionTest.java +87 −14 Original line number Diff line number Diff line Loading @@ -19,11 +19,14 @@ import static com.google.common.truth.Truth.assertThat; import static org.testng.Assert.assertThrows; import android.view.View; import android.view.ViewStructure; import android.view.autofill.AutofillId; import android.view.contentcapture.ViewNode.ViewStructureImpl; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Spy; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; /** Loading @@ -35,34 +38,104 @@ import org.mockito.junit.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.class) public class ContentCaptureSessionTest { /** * Uses a spy as ContentCaptureSession is abstract but (so far) we're testing its concrete * methods. */ @Spy private ContentCaptureSession mMockSession; private ContentCaptureSession mSession1 = new MyContentCaptureSession("111"); private ContentCaptureSession mSession2 = new MyContentCaptureSession("2222"); @Mock private View mMockView; @Test public void testNewAutofillId_invalid() { assertThrows(NullPointerException.class, () -> mMockSession.newAutofillId(null, 42)); assertThrows(NullPointerException.class, () -> mSession1.newAutofillId(null, 42)); assertThrows(IllegalArgumentException.class, () -> mMockSession.newAutofillId(new AutofillId(42, 42), 42)); () -> mSession1.newAutofillId(new AutofillId(42, 42), 42)); } @Test public void testNewAutofillId_valid() { final AutofillId parentId = new AutofillId(42); final AutofillId childId = mMockSession.newAutofillId(parentId, 108); final AutofillId childId = mSession1.newAutofillId(parentId, 108); assertThat(childId.getViewId()).isEqualTo(42); assertThat(childId.getVirtualChildId()).isEqualTo(108); // TODO(b/121197119): assert session id assertThat(childId.getSessionId()).isEqualTo(mSession1.getIdAsInt()); } @Test public void testNewAutofillId_differentSessions() { assertThat(mSession1.getIdAsInt()).isNotSameAs(mSession2.getIdAsInt()); //sanity check final AutofillId parentId = new AutofillId(42); final AutofillId childId1 = mSession1.newAutofillId(parentId, 108); final AutofillId childId2 = mSession2.newAutofillId(parentId, 108); assertThat(childId1).isNotEqualTo(childId2); assertThat(childId2).isNotEqualTo(childId1); } @Test public void testNotifyXXX_null() { assertThrows(NullPointerException.class, () -> mMockSession.notifyViewAppeared(null)); assertThrows(NullPointerException.class, () -> mMockSession.notifyViewDisappeared(null)); assertThrows(NullPointerException.class, () -> mSession1.notifyViewAppeared(null)); assertThrows(NullPointerException.class, () -> mSession1.notifyViewDisappeared(null)); assertThrows(NullPointerException.class, () -> mMockSession.notifyViewTextChanged(null, "whatever", 0)); () -> mSession1.notifyViewTextChanged(null, "whatever", 0)); } @Test public void testNewViewStructure() { assertThat(mMockView.getAutofillId()).isNotNull(); // sanity check final ViewStructure structure = mSession1.newViewStructure(mMockView); assertThat(structure).isNotNull(); assertThat(structure.getAutofillId()).isEqualTo(mMockView.getAutofillId()); } @Test public void testNewVirtualViewStructure() { final AutofillId parentId = new AutofillId(42); final ViewStructure structure = mSession1.newVirtualViewStructure(parentId, 108); assertThat(structure).isNotNull(); final AutofillId childId = mSession1.newAutofillId(parentId, 108); assertThat(structure.getAutofillId()).isEqualTo(childId); } // Cannot use @Spy because we need to pass the session id on constructor private class MyContentCaptureSession extends ContentCaptureSession { private MyContentCaptureSession(String id) { super(id); } @Override MainContentCaptureSession getMainCaptureSession() { throw new UnsupportedOperationException("should not have been called"); } @Override ContentCaptureSession newChild(ContentCaptureContext context) { throw new UnsupportedOperationException("should not have been called"); } @Override void flush() { throw new UnsupportedOperationException("should not have been called"); } @Override void onDestroy() { throw new UnsupportedOperationException("should not have been called"); } @Override void internalNotifyViewAppeared(ViewStructureImpl node) { throw new UnsupportedOperationException("should not have been called"); } @Override void internalNotifyViewDisappeared(AutofillId id) { throw new UnsupportedOperationException("should not have been called"); } @Override void internalNotifyViewTextChanged(AutofillId id, CharSequence text, int flags) { throw new UnsupportedOperationException("should not have been called"); } } }