Skip to content

Commit 248bde5

Browse files
author
Android Build Coastguard Worker
committed
Merge cherrypicks of ['googleplex-android-review.googlesource.com/21027159', 'googleplex-android-review.googlesource.com/23517237', 'googleplex-android-review.googlesource.com/23770590', 'googleplex-android-review.googlesource.com/23892147', 'googleplex-android-review.googlesource.com/23877018', 'googleplex-android-review.googlesource.com/23785419', 'googleplex-android-review.googlesource.com/23817819', 'googleplex-android-review.googlesource.com/23835332', 'googleplex-android-review.googlesource.com/23436487', 'googleplex-android-review.googlesource.com/24057913', 'googleplex-android-review.googlesource.com/24212143', 'googleplex-android-review.googlesource.com/24300599'] into tm-platform-release.
Change-Id: If074f61e64626640de606f94bd82a7ac0065de01
2 parents 502a47c + 72c2f96 commit 248bde5

113 files changed

Lines changed: 627 additions & 161 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

core/java/android/app/Notification.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2862,8 +2862,9 @@ public void visitUris(@NonNull Consumer<Uri> visitor) {
28622862
visitor.accept(person.getIconUri());
28632863
}
28642864

2865-
final RemoteInputHistoryItem[] history = (RemoteInputHistoryItem[])
2866-
extras.getParcelableArray(Notification.EXTRA_REMOTE_INPUT_HISTORY_ITEMS);
2865+
final RemoteInputHistoryItem[] history = extras.getParcelableArray(
2866+
Notification.EXTRA_REMOTE_INPUT_HISTORY_ITEMS,
2867+
RemoteInputHistoryItem.class);
28672868
if (history != null) {
28682869
for (int i = 0; i < history.length; i++) {
28692870
RemoteInputHistoryItem item = history[i];

core/java/android/database/DatabaseUtils.java

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -511,17 +511,31 @@ public static void cursorFillWindow(final Cursor cursor,
511511
*/
512512
public static void appendEscapedSQLString(StringBuilder sb, String sqlString) {
513513
sb.append('\'');
514-
if (sqlString.indexOf('\'') != -1) {
515-
int length = sqlString.length();
516-
for (int i = 0; i < length; i++) {
517-
char c = sqlString.charAt(i);
518-
if (c == '\'') {
519-
sb.append('\'');
514+
int length = sqlString.length();
515+
for (int i = 0; i < length; i++) {
516+
char c = sqlString.charAt(i);
517+
if (Character.isHighSurrogate(c)) {
518+
if (i == length - 1) {
519+
continue;
520+
}
521+
if (Character.isLowSurrogate(sqlString.charAt(i + 1))) {
522+
// add them both
523+
sb.append(c);
524+
sb.append(sqlString.charAt(i + 1));
525+
continue;
526+
} else {
527+
// this is a lone surrogate, skip it
528+
continue;
520529
}
521-
sb.append(c);
522530
}
523-
} else
524-
sb.append(sqlString);
531+
if (Character.isLowSurrogate(c)) {
532+
continue;
533+
}
534+
if (c == '\'') {
535+
sb.append('\'');
536+
}
537+
sb.append(c);
538+
}
525539
sb.append('\'');
526540
}
527541

core/java/android/net/Uri.java

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -882,10 +882,11 @@ private OpaqueUri(String scheme, Part ssp, Part fragment) {
882882
}
883883

884884
static Uri readFrom(Parcel parcel) {
885+
final StringUri stringUri = new StringUri(parcel.readString8());
885886
return new OpaqueUri(
886-
parcel.readString8(),
887-
Part.readFrom(parcel),
888-
Part.readFrom(parcel)
887+
stringUri.parseScheme(),
888+
stringUri.getSsp(),
889+
stringUri.getFragmentPart()
889890
);
890891
}
891892

@@ -895,9 +896,7 @@ public int describeContents() {
895896

896897
public void writeToParcel(Parcel parcel, int flags) {
897898
parcel.writeInt(TYPE_ID);
898-
parcel.writeString8(scheme);
899-
ssp.writeTo(parcel);
900-
fragment.writeTo(parcel);
899+
parcel.writeString8(toString());
901900
}
902901

903902
public boolean isHierarchical() {
@@ -1196,22 +1195,25 @@ private HierarchicalUri(String scheme, Part authority, PathPart path,
11961195
Part query, Part fragment) {
11971196
this.scheme = scheme;
11981197
this.authority = Part.nonNull(authority);
1199-
this.path = path == null ? PathPart.NULL : path;
1198+
this.path = generatePath(path);
12001199
this.query = Part.nonNull(query);
12011200
this.fragment = Part.nonNull(fragment);
12021201
}
12031202

1204-
static Uri readFrom(Parcel parcel) {
1205-
final String scheme = parcel.readString8();
1206-
final Part authority = Part.readFrom(parcel);
1203+
private PathPart generatePath(PathPart originalPath) {
12071204
// In RFC3986 the path should be determined based on whether there is a scheme or
12081205
// authority present (https://www.rfc-editor.org/rfc/rfc3986.html#section-3.3).
12091206
final boolean hasSchemeOrAuthority =
12101207
(scheme != null && scheme.length() > 0) || !authority.isEmpty();
1211-
final PathPart path = PathPart.readFrom(hasSchemeOrAuthority, parcel);
1212-
final Part query = Part.readFrom(parcel);
1213-
final Part fragment = Part.readFrom(parcel);
1214-
return new HierarchicalUri(scheme, authority, path, query, fragment);
1208+
final PathPart newPath = hasSchemeOrAuthority ? PathPart.makeAbsolute(originalPath)
1209+
: originalPath;
1210+
return newPath == null ? PathPart.NULL : newPath;
1211+
}
1212+
1213+
static Uri readFrom(Parcel parcel) {
1214+
final StringUri stringUri = new StringUri(parcel.readString8());
1215+
return new HierarchicalUri(stringUri.getScheme(), stringUri.getAuthorityPart(),
1216+
stringUri.getPathPart(), stringUri.getQueryPart(), stringUri.getFragmentPart());
12151217
}
12161218

12171219
public int describeContents() {
@@ -1220,11 +1222,7 @@ public int describeContents() {
12201222

12211223
public void writeToParcel(Parcel parcel, int flags) {
12221224
parcel.writeInt(TYPE_ID);
1223-
parcel.writeString8(scheme);
1224-
authority.writeTo(parcel);
1225-
path.writeTo(parcel);
1226-
query.writeTo(parcel);
1227-
fragment.writeTo(parcel);
1225+
parcel.writeString8(toString());
12281226
}
12291227

12301228
public boolean isHierarchical() {

core/jni/android_view_InputDevice.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,22 @@ jobject android_view_InputDevice_create(JNIEnv* env, const InputDeviceInfo& devi
4242
return NULL;
4343
}
4444

45+
// b/274058082: Pass a copy of the key character map to avoid concurrent
46+
// access
47+
std::shared_ptr<KeyCharacterMap> map = deviceInfo.getKeyCharacterMap();
48+
if (map != nullptr) {
49+
map = std::make_shared<KeyCharacterMap>(*map);
50+
}
51+
4552
ScopedLocalRef<jstring> descriptorObj(env,
4653
env->NewStringUTF(deviceInfo.getIdentifier().descriptor.c_str()));
4754
if (!descriptorObj.get()) {
4855
return NULL;
4956
}
5057

5158
ScopedLocalRef<jobject> kcmObj(env,
52-
android_view_KeyCharacterMap_create(env, deviceInfo.getId(),
53-
deviceInfo.getKeyCharacterMap()));
59+
android_view_KeyCharacterMap_create(env, deviceInfo.getId(),
60+
map));
5461
if (!kcmObj.get()) {
5562
return NULL;
5663
}

core/tests/coretests/src/android/net/UriTest.java

Lines changed: 60 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@
2525

2626
import java.io.File;
2727
import java.lang.reflect.Constructor;
28-
import java.lang.reflect.InvocationTargetException;
29-
import java.lang.reflect.Method;
3028
import java.util.Arrays;
3129
import java.util.Iterator;
3230
import java.util.List;
@@ -869,84 +867,90 @@ private static Uri makeHierarchicalUri(Object authority, Object path) throws Exc
869867
return (Uri) hierarchicalUriConstructor.newInstance("https", authority, path, null, null);
870868
}
871869

872-
/** Attempting to unparcel a legacy parcel format of Uri.{,Path}Part should fail. */
873-
public void testUnparcelLegacyPart_fails() throws Exception {
874-
assertUnparcelLegacyPart_fails(Class.forName("android.net.Uri$Part"));
875-
assertUnparcelLegacyPart_fails(Class.forName("android.net.Uri$PathPart"));
876-
}
877-
878-
private static void assertUnparcelLegacyPart_fails(Class partClass) throws Exception {
879-
Parcel parcel = Parcel.obtain();
880-
parcel.writeInt(0 /* BOTH */);
881-
parcel.writeString("encoded");
882-
parcel.writeString("decoded");
883-
parcel.setDataPosition(0);
884-
885-
Method readFromMethod = partClass.getDeclaredMethod("readFrom", Parcel.class);
886-
readFromMethod.setAccessible(true);
887-
try {
888-
readFromMethod.invoke(null, parcel);
889-
fail();
890-
} catch (InvocationTargetException expected) {
891-
Throwable targetException = expected.getTargetException();
892-
// Check that the exception was thrown for the correct reason.
893-
assertEquals("Unknown representation: 0", targetException.getMessage());
894-
} finally {
895-
parcel.recycle();
896-
}
897-
}
898-
899-
private Uri buildUriFromRawParcel(boolean argumentsEncoded,
870+
private Uri buildUriFromParts(boolean argumentsEncoded,
900871
String scheme,
901872
String authority,
902873
String path,
903874
String query,
904875
String fragment) {
905-
// Representation value (from AbstractPart.REPRESENTATION_{ENCODED,DECODED}).
906-
final int representation = argumentsEncoded ? 1 : 2;
907-
Parcel parcel = Parcel.obtain();
908-
try {
909-
parcel.writeInt(3); // hierarchical
910-
parcel.writeString8(scheme);
911-
parcel.writeInt(representation);
912-
parcel.writeString8(authority);
913-
parcel.writeInt(representation);
914-
parcel.writeString8(path);
915-
parcel.writeInt(representation);
916-
parcel.writeString8(query);
917-
parcel.writeInt(representation);
918-
parcel.writeString8(fragment);
919-
parcel.setDataPosition(0);
920-
return Uri.CREATOR.createFromParcel(parcel);
921-
} finally {
922-
parcel.recycle();
876+
final Uri.Builder builder = new Uri.Builder();
877+
builder.scheme(scheme);
878+
if (argumentsEncoded) {
879+
builder.encodedAuthority(authority);
880+
builder.encodedPath(path);
881+
builder.encodedQuery(query);
882+
builder.encodedFragment(fragment);
883+
} else {
884+
builder.authority(authority);
885+
builder.path(path);
886+
builder.query(query);
887+
builder.fragment(fragment);
923888
}
889+
return builder.build();
924890
}
925891

926892
public void testUnparcelMalformedPath() {
927893
// Regression tests for b/171966843.
928894

929895
// Test cases with arguments encoded (covering testing `scheme` * `authority` options).
930-
Uri uri0 = buildUriFromRawParcel(true, "https", "google.com", "@evil.com", null, null);
896+
Uri uri0 = buildUriFromParts(true, "https", "google.com", "@evil.com", null, null);
931897
assertEquals("https://google.com/@evil.com", uri0.toString());
932-
Uri uri1 = buildUriFromRawParcel(true, null, "google.com", "@evil.com", "name=spark", "x");
898+
Uri uri1 = buildUriFromParts(true, null, "google.com", "@evil.com", "name=spark", "x");
933899
assertEquals("//google.com/@evil.com?name=spark#x", uri1.toString());
934-
Uri uri2 = buildUriFromRawParcel(true, "http:", null, "@evil.com", null, null);
900+
Uri uri2 = buildUriFromParts(true, "http:", null, "@evil.com", null, null);
935901
assertEquals("http::/@evil.com", uri2.toString());
936-
Uri uri3 = buildUriFromRawParcel(true, null, null, "@evil.com", null, null);
902+
Uri uri3 = buildUriFromParts(true, null, null, "@evil.com", null, null);
937903
assertEquals("@evil.com", uri3.toString());
938904

939905
// Test cases with arguments not encoded (covering testing `scheme` * `authority` options).
940-
Uri uriA = buildUriFromRawParcel(false, "https", "google.com", "@evil.com", null, null);
906+
Uri uriA = buildUriFromParts(false, "https", "google.com", "@evil.com", null, null);
941907
assertEquals("https://google.com/%40evil.com", uriA.toString());
942-
Uri uriB = buildUriFromRawParcel(false, null, "google.com", "@evil.com", null, null);
908+
Uri uriB = buildUriFromParts(false, null, "google.com", "@evil.com", null, null);
943909
assertEquals("//google.com/%40evil.com", uriB.toString());
944-
Uri uriC = buildUriFromRawParcel(false, "http:", null, "@evil.com", null, null);
910+
Uri uriC = buildUriFromParts(false, "http:", null, "@evil.com", null, null);
945911
assertEquals("http::/%40evil.com", uriC.toString());
946-
Uri uriD = buildUriFromRawParcel(false, null, null, "@evil.com", "name=spark", "y");
912+
Uri uriD = buildUriFromParts(false, null, null, "@evil.com", "name=spark", "y");
947913
assertEquals("%40evil.com?name%3Dspark#y", uriD.toString());
948914
}
949915

916+
public void testParsedUriFromStringEquality() {
917+
Uri uri = buildUriFromParts(
918+
true, "https", "google.com", "@evil.com", null, null);
919+
assertEquals(uri, Uri.parse(uri.toString()));
920+
Uri uri2 = buildUriFromParts(
921+
true, "content://evil.authority?foo=", "safe.authority", "@evil.com", null, null);
922+
assertEquals(uri2, Uri.parse(uri2.toString()));
923+
Uri uri3 = buildUriFromParts(
924+
false, "content://evil.authority?foo=", "safe.authority", "@evil.com", null, null);
925+
assertEquals(uri3, Uri.parse(uri3.toString()));
926+
}
927+
928+
public void testParceledUrisAreEqual() {
929+
Uri opaqueUri = Uri.fromParts("fake://uri#", "ssp", "fragment");
930+
Parcel parcel = Parcel.obtain();
931+
try {
932+
opaqueUri.writeToParcel(parcel, 0);
933+
parcel.setDataPosition(0);
934+
Uri postParcelUri = Uri.CREATOR.createFromParcel(parcel);
935+
Uri parsedUri = Uri.parse(postParcelUri.toString());
936+
assertEquals(parsedUri.getScheme(), postParcelUri.getScheme());
937+
} finally {
938+
parcel.recycle();
939+
}
940+
941+
Uri hierarchicalUri = new Uri.Builder().scheme("fake://uri#").authority("auth").build();
942+
parcel = Parcel.obtain();
943+
try {
944+
hierarchicalUri.writeToParcel(parcel, 0);
945+
parcel.setDataPosition(0);
946+
Uri postParcelUri = Uri.CREATOR.createFromParcel(parcel);
947+
Uri parsedUri = Uri.parse(postParcelUri.toString());
948+
assertEquals(parsedUri.getScheme(), postParcelUri.getScheme());
949+
} finally {
950+
parcel.recycle();
951+
}
952+
}
953+
950954
public void testToSafeString() {
951955
checkToSafeString("tel:xxxxxx", "tel:Google");
952956
checkToSafeString("tel:xxxxxxxxxx", "tel:1234567890");

libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
import android.graphics.Color;
4646
import android.graphics.Rect;
4747
import android.graphics.drawable.Drawable;
48+
import android.graphics.drawable.Icon;
4849
import android.net.Uri;
4950
import android.os.Bundle;
5051
import android.os.Handler;
@@ -513,13 +514,19 @@ private void updateActionViews(int menuState, Rect stackBounds) {
513514
final boolean isCloseAction = mCloseAction != null && Objects.equals(
514515
mCloseAction.getActionIntent(), action.getActionIntent());
515516

516-
// TODO: Check if the action drawable has changed before we reload it
517-
action.getIcon().loadDrawableAsync(mContext, d -> {
518-
if (d != null) {
519-
d.setTint(Color.WHITE);
520-
actionView.setImageDrawable(d);
521-
}
522-
}, mMainHandler);
517+
final int iconType = action.getIcon().getType();
518+
if (iconType == Icon.TYPE_URI || iconType == Icon.TYPE_URI_ADAPTIVE_BITMAP) {
519+
// Disallow loading icon from content URI
520+
actionView.setImageDrawable(null);
521+
} else {
522+
// TODO: Check if the action drawable has changed before we reload it
523+
action.getIcon().loadDrawableAsync(mContext, d -> {
524+
if (d != null) {
525+
d.setTint(Color.WHITE);
526+
actionView.setImageDrawable(d);
527+
}
528+
}, mMainHandler);
529+
}
523530
actionView.setCustomCloseBackgroundVisibility(
524531
isCloseAction ? View.VISIBLE : View.GONE);
525532
actionView.setContentDescription(action.getContentDescription());

media/java/android/media/RingtoneManager.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -814,10 +814,10 @@ public static Uri getActualDefaultRingtoneUri(Context context, int type) {
814814

815815
return ringtoneUri;
816816
}
817-
817+
818818
/**
819819
* Sets the {@link Uri} of the default sound for a given sound type.
820-
*
820+
*
821821
* @param context A context used for querying.
822822
* @param type The type whose default sound should be set. One of
823823
* {@link #TYPE_RINGTONE}, {@link #TYPE_NOTIFICATION}, or
@@ -833,6 +833,21 @@ public static void setActualDefaultRingtoneUri(Context context, int type, Uri ri
833833
if(!isInternalRingtoneUri(ringtoneUri)) {
834834
ringtoneUri = ContentProvider.maybeAddUserId(ringtoneUri, context.getUserId());
835835
}
836+
837+
if (ringtoneUri != null) {
838+
final String mimeType = resolver.getType(ringtoneUri);
839+
if (mimeType == null) {
840+
Log.e(TAG, "setActualDefaultRingtoneUri for URI:" + ringtoneUri
841+
+ " ignored: failure to find mimeType (no access from this context?)");
842+
return;
843+
}
844+
if (!(mimeType.startsWith("audio/") || mimeType.equals("application/ogg"))) {
845+
Log.e(TAG, "setActualDefaultRingtoneUri for URI:" + ringtoneUri
846+
+ " ignored: associated mimeType:" + mimeType + " is not an audio type");
847+
return;
848+
}
849+
}
850+
836851
Settings.System.putStringForUser(resolver, setting,
837852
ringtoneUri != null ? ringtoneUri.toString() : null, context.getUserId());
838853

0 commit comments

Comments
 (0)