diff --git a/core/java/android/content/pm/Signature.java b/core/java/android/content/pm/Signature.java index 02fb06b808a22..bce4b872b8a6d 100644 --- a/core/java/android/content/pm/Signature.java +++ b/core/java/android/content/pm/Signature.java @@ -256,6 +256,8 @@ public class Signature implements Parcelable { try { if (obj != null) { Signature other = (Signature)obj; + // Note, some classes, such as PackageParser.SigningDetails, rely on equals + // only comparing the mSignature arrays without the flags. return this == other || Arrays.equals(mSignature, other.mSignature); } } catch (ClassCastException e) { @@ -268,6 +270,8 @@ public class Signature implements Parcelable { if (mHaveHashCode) { return mHashCode; } + // Note, similar to equals some classes rely on the hash code not including + // the flags for Set membership checks. mHashCode = Arrays.hashCode(mSignature); mHaveHashCode = true; return mHashCode; diff --git a/core/tests/coretests/src/android/content/pm/SignatureTest.java b/core/tests/coretests/src/android/content/pm/SignatureTest.java index f0b4af6fc44f9..19458da796e8f 100644 --- a/core/tests/coretests/src/android/content/pm/SignatureTest.java +++ b/core/tests/coretests/src/android/content/pm/SignatureTest.java @@ -54,6 +54,32 @@ public class SignatureTest extends TestCase { assertFalse(Signature.areEffectiveMatch(asArray(A, M), asArray(A, B))); } + public void testHashCode_doesNotIncludeFlags() throws Exception { + // Some classes rely on the hash code not including the flags / capabilities for the signer + // to verify Set membership. This test verifies two signers with the same signature but + // different flags have the same hash code. + Signature signatureAWithAllCaps = new Signature(A.toCharsString()); + // There are currently 5 capabilities that can be assigned to a previous signer, although + // for the purposes of this test all that matters is that the two flag values are distinct. + signatureAWithAllCaps.setFlags(31); + Signature signatureAWithNoCaps = new Signature(A.toCharsString()); + signatureAWithNoCaps.setFlags(0); + + assertEquals(signatureAWithAllCaps.hashCode(), signatureAWithNoCaps.hashCode()); + } + + public void testEquals_doesNotIncludeFlags() throws Exception { + // Similar to above some classes rely on equals only comparing the signature arrays + // for equality without including the flags. This test verifies two signers with the + // same signature but different flags are still considered equal. + Signature signatureAWithAllCaps = new Signature(A.toCharsString()); + signatureAWithAllCaps.setFlags(31); + Signature signatureAWithNoCaps = new Signature(A.toCharsString()); + signatureAWithNoCaps.setFlags(0); + + assertEquals(signatureAWithAllCaps, signatureAWithNoCaps); + } + private static Signature[] asArray(Signature... s) { return s; }