Merge "Revert "Update parcling logic for Uris."" into rvc-dev am: d926f4f2a2 am: ccc748a0d7 am: 2929859166 am: b11212b320 am: 3569c11009 am: 22454204a6 am: bf624d549f
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/25023593
Change-Id: I99b0be9a800ee1397dfd1e62b26547853aba370c
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/core/java/android/net/Uri.java b/core/java/android/net/Uri.java
index 7fbaf10..3da696a 100644
--- a/core/java/android/net/Uri.java
+++ b/core/java/android/net/Uri.java
@@ -882,11 +882,10 @@
}
static Uri readFrom(Parcel parcel) {
- final StringUri stringUri = new StringUri(parcel.readString8());
return new OpaqueUri(
- stringUri.parseScheme(),
- stringUri.getSsp(),
- stringUri.getFragmentPart()
+ parcel.readString8(),
+ Part.readFrom(parcel),
+ Part.readFrom(parcel)
);
}
@@ -896,7 +895,9 @@
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeInt(TYPE_ID);
- parcel.writeString8(toString());
+ parcel.writeString8(scheme);
+ ssp.writeTo(parcel);
+ fragment.writeTo(parcel);
}
public boolean isHierarchical() {
@@ -1195,25 +1196,22 @@
Part query, Part fragment) {
this.scheme = scheme;
this.authority = Part.nonNull(authority);
- this.path = generatePath(path);
+ this.path = path == null ? PathPart.NULL : path;
this.query = Part.nonNull(query);
this.fragment = Part.nonNull(fragment);
}
- private PathPart generatePath(PathPart originalPath) {
+ static Uri readFrom(Parcel parcel) {
+ final String scheme = parcel.readString8();
+ final Part authority = Part.readFrom(parcel);
// In RFC3986 the path should be determined based on whether there is a scheme or
// authority present (https://www.rfc-editor.org/rfc/rfc3986.html#section-3.3).
final boolean hasSchemeOrAuthority =
(scheme != null && scheme.length() > 0) || !authority.isEmpty();
- final PathPart newPath = hasSchemeOrAuthority ? PathPart.makeAbsolute(originalPath)
- : originalPath;
- return newPath == null ? PathPart.NULL : newPath;
- }
-
- static Uri readFrom(Parcel parcel) {
- final StringUri stringUri = new StringUri(parcel.readString8());
- return new HierarchicalUri(stringUri.getScheme(), stringUri.getAuthorityPart(),
- stringUri.getPathPart(), stringUri.getQueryPart(), stringUri.getFragmentPart());
+ final PathPart path = PathPart.readFrom(hasSchemeOrAuthority, parcel);
+ final Part query = Part.readFrom(parcel);
+ final Part fragment = Part.readFrom(parcel);
+ return new HierarchicalUri(scheme, authority, path, query, fragment);
}
public int describeContents() {
@@ -1222,7 +1220,11 @@
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeInt(TYPE_ID);
- parcel.writeString8(toString());
+ parcel.writeString8(scheme);
+ authority.writeTo(parcel);
+ path.writeTo(parcel);
+ query.writeTo(parcel);
+ fragment.writeTo(parcel);
}
public boolean isHierarchical() {
diff --git a/core/tests/coretests/src/android/net/UriTest.java b/core/tests/coretests/src/android/net/UriTest.java
index 2a4ca79..89632a4 100644
--- a/core/tests/coretests/src/android/net/UriTest.java
+++ b/core/tests/coretests/src/android/net/UriTest.java
@@ -25,6 +25,8 @@
import java.io.File;
import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
@@ -867,90 +869,84 @@
return (Uri) hierarchicalUriConstructor.newInstance("https", authority, path, null, null);
}
- private Uri buildUriFromParts(boolean argumentsEncoded,
+ /** Attempting to unparcel a legacy parcel format of Uri.{,Path}Part should fail. */
+ public void testUnparcelLegacyPart_fails() throws Exception {
+ assertUnparcelLegacyPart_fails(Class.forName("android.net.Uri$Part"));
+ assertUnparcelLegacyPart_fails(Class.forName("android.net.Uri$PathPart"));
+ }
+
+ private static void assertUnparcelLegacyPart_fails(Class partClass) throws Exception {
+ Parcel parcel = Parcel.obtain();
+ parcel.writeInt(0 /* BOTH */);
+ parcel.writeString("encoded");
+ parcel.writeString("decoded");
+ parcel.setDataPosition(0);
+
+ Method readFromMethod = partClass.getDeclaredMethod("readFrom", Parcel.class);
+ readFromMethod.setAccessible(true);
+ try {
+ readFromMethod.invoke(null, parcel);
+ fail();
+ } catch (InvocationTargetException expected) {
+ Throwable targetException = expected.getTargetException();
+ // Check that the exception was thrown for the correct reason.
+ assertEquals("Unknown representation: 0", targetException.getMessage());
+ } finally {
+ parcel.recycle();
+ }
+ }
+
+ private Uri buildUriFromRawParcel(boolean argumentsEncoded,
String scheme,
String authority,
String path,
String query,
String fragment) {
- final Uri.Builder builder = new Uri.Builder();
- builder.scheme(scheme);
- if (argumentsEncoded) {
- builder.encodedAuthority(authority);
- builder.encodedPath(path);
- builder.encodedQuery(query);
- builder.encodedFragment(fragment);
- } else {
- builder.authority(authority);
- builder.path(path);
- builder.query(query);
- builder.fragment(fragment);
+ // Representation value (from AbstractPart.REPRESENTATION_{ENCODED,DECODED}).
+ final int representation = argumentsEncoded ? 1 : 2;
+ Parcel parcel = Parcel.obtain();
+ try {
+ parcel.writeInt(3); // hierarchical
+ parcel.writeString8(scheme);
+ parcel.writeInt(representation);
+ parcel.writeString8(authority);
+ parcel.writeInt(representation);
+ parcel.writeString8(path);
+ parcel.writeInt(representation);
+ parcel.writeString8(query);
+ parcel.writeInt(representation);
+ parcel.writeString8(fragment);
+ parcel.setDataPosition(0);
+ return Uri.CREATOR.createFromParcel(parcel);
+ } finally {
+ parcel.recycle();
}
- return builder.build();
}
public void testUnparcelMalformedPath() {
// Regression tests for b/171966843.
// Test cases with arguments encoded (covering testing `scheme` * `authority` options).
- Uri uri0 = buildUriFromParts(true, "https", "google.com", "@evil.com", null, null);
+ Uri uri0 = buildUriFromRawParcel(true, "https", "google.com", "@evil.com", null, null);
assertEquals("https://google.com/@evil.com", uri0.toString());
- Uri uri1 = buildUriFromParts(true, null, "google.com", "@evil.com", "name=spark", "x");
+ Uri uri1 = buildUriFromRawParcel(true, null, "google.com", "@evil.com", "name=spark", "x");
assertEquals("//google.com/@evil.com?name=spark#x", uri1.toString());
- Uri uri2 = buildUriFromParts(true, "http:", null, "@evil.com", null, null);
+ Uri uri2 = buildUriFromRawParcel(true, "http:", null, "@evil.com", null, null);
assertEquals("http::/@evil.com", uri2.toString());
- Uri uri3 = buildUriFromParts(true, null, null, "@evil.com", null, null);
+ Uri uri3 = buildUriFromRawParcel(true, null, null, "@evil.com", null, null);
assertEquals("@evil.com", uri3.toString());
// Test cases with arguments not encoded (covering testing `scheme` * `authority` options).
- Uri uriA = buildUriFromParts(false, "https", "google.com", "@evil.com", null, null);
+ Uri uriA = buildUriFromRawParcel(false, "https", "google.com", "@evil.com", null, null);
assertEquals("https://google.com/%40evil.com", uriA.toString());
- Uri uriB = buildUriFromParts(false, null, "google.com", "@evil.com", null, null);
+ Uri uriB = buildUriFromRawParcel(false, null, "google.com", "@evil.com", null, null);
assertEquals("//google.com/%40evil.com", uriB.toString());
- Uri uriC = buildUriFromParts(false, "http:", null, "@evil.com", null, null);
+ Uri uriC = buildUriFromRawParcel(false, "http:", null, "@evil.com", null, null);
assertEquals("http::/%40evil.com", uriC.toString());
- Uri uriD = buildUriFromParts(false, null, null, "@evil.com", "name=spark", "y");
+ Uri uriD = buildUriFromRawParcel(false, null, null, "@evil.com", "name=spark", "y");
assertEquals("%40evil.com?name%3Dspark#y", uriD.toString());
}
- public void testParsedUriFromStringEquality() {
- Uri uri = buildUriFromParts(
- true, "https", "google.com", "@evil.com", null, null);
- assertEquals(uri, Uri.parse(uri.toString()));
- Uri uri2 = buildUriFromParts(
- true, "content://evil.authority?foo=", "safe.authority", "@evil.com", null, null);
- assertEquals(uri2, Uri.parse(uri2.toString()));
- Uri uri3 = buildUriFromParts(
- false, "content://evil.authority?foo=", "safe.authority", "@evil.com", null, null);
- assertEquals(uri3, Uri.parse(uri3.toString()));
- }
-
- public void testParceledUrisAreEqual() {
- Uri opaqueUri = Uri.fromParts("fake://uri#", "ssp", "fragment");
- Parcel parcel = Parcel.obtain();
- try {
- opaqueUri.writeToParcel(parcel, 0);
- parcel.setDataPosition(0);
- Uri postParcelUri = Uri.CREATOR.createFromParcel(parcel);
- Uri parsedUri = Uri.parse(postParcelUri.toString());
- assertEquals(parsedUri.getScheme(), postParcelUri.getScheme());
- } finally {
- parcel.recycle();
- }
-
- Uri hierarchicalUri = new Uri.Builder().scheme("fake://uri#").authority("auth").build();
- parcel = Parcel.obtain();
- try {
- hierarchicalUri.writeToParcel(parcel, 0);
- parcel.setDataPosition(0);
- Uri postParcelUri = Uri.CREATOR.createFromParcel(parcel);
- Uri parsedUri = Uri.parse(postParcelUri.toString());
- assertEquals(parsedUri.getScheme(), postParcelUri.getScheme());
- } finally {
- parcel.recycle();
- }
- }
-
public void testToSafeString() {
checkToSafeString("tel:xxxxxx", "tel:Google");
checkToSafeString("tel:xxxxxxxxxx", "tel:1234567890");