Skip to content

Commit 2e824c9

Browse files
committed
Merge tag 'android-security-13.0.0_r14' into cr-11.0
Android Security 13.0.0 Release 14 (11228180) Change-Id: I0516e78435f18b6d626dfe8cdc2cfd5f70cf4e6c
2 parents 6c42754 + 09383fb commit 2e824c9

File tree

32 files changed

+1428
-627
lines changed

32 files changed

+1428
-627
lines changed

core/java/android/content/Context.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,7 @@ public abstract class Context {
272272
BIND_IMPORTANT,
273273
BIND_ADJUST_WITH_ACTIVITY,
274274
BIND_NOT_PERCEPTIBLE,
275+
BIND_DENY_ACTIVITY_STARTS_PRE_34,
275276
BIND_INCLUDE_CAPABILITIES
276277
})
277278
@Retention(RetentionPolicy.SOURCE)
@@ -392,6 +393,14 @@ public abstract class Context {
392393
/*********** Public flags above this line ***********/
393394
/*********** Hidden flags below this line ***********/
394395

396+
/**
397+
* Flag for {@link #bindService}: If binding from an app that is visible, the bound service is
398+
* allowed to start an activity from background. Add a flag so that this behavior can be opted
399+
* out.
400+
* @hide
401+
*/
402+
public static final int BIND_DENY_ACTIVITY_STARTS_PRE_34 = 0X000004000;
403+
395404
/**
396405
* Flag for {@link #bindService}: This flag is only intended to be used by the system to
397406
* indicate that a service binding is not considered as real package component usage and should

core/java/android/provider/Settings.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9731,6 +9731,13 @@ public static boolean putFloatForUser(ContentResolver cr, String name, float val
97319731
*/
97329732
public static final String SPATIAL_AUDIO_ENABLED = "spatial_audio_enabled";
97339733

9734+
/**
9735+
* Internal collection of audio device inventory items
9736+
* The device item stored are {@link com.android.server.audio.AdiDeviceState}
9737+
* @hide
9738+
*/
9739+
public static final String AUDIO_DEVICE_INVENTORY = "audio_device_inventory";
9740+
97349741
/**
97359742
* Indicates whether notification display on the lock screen is enabled.
97369743
* <p>

core/java/com/android/internal/content/FileSystemProvider.java

Lines changed: 88 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,14 @@
6262
import java.nio.file.Files;
6363
import java.nio.file.Path;
6464
import java.nio.file.attribute.BasicFileAttributes;
65+
import java.util.ArrayDeque;
6566
import java.util.Arrays;
6667
import java.util.LinkedList;
6768
import java.util.List;
6869
import java.util.Locale;
70+
import java.util.Queue;
6971
import java.util.Set;
7072
import java.util.concurrent.CopyOnWriteArrayList;
71-
import java.util.function.Predicate;
72-
import java.util.regex.Pattern;
7373

7474
/**
7575
* A helper class for {@link android.provider.DocumentsProvider} to perform file operations on local
@@ -87,6 +87,8 @@ public abstract class FileSystemProvider extends DocumentsProvider {
8787
DocumentsContract.QUERY_ARG_LAST_MODIFIED_AFTER,
8888
DocumentsContract.QUERY_ARG_MIME_TYPES);
8989

90+
private static final int MAX_RESULTS_NUMBER = 23;
91+
9092
private static String joinNewline(String... args) {
9193
return TextUtils.join("\n", args);
9294
}
@@ -373,62 +375,53 @@ public Cursor queryDocument(String documentId, String[] projection)
373375
}
374376

375377
/**
376-
* This method is similar to
377-
* {@link DocumentsProvider#queryChildDocuments(String, String[], String)}. This method returns
378-
* all children documents including hidden directories/files.
379-
*
380-
* <p>
381-
* In a scoped storage world, access to "Android/data" style directories are hidden for privacy
382-
* reasons. This method may show privacy sensitive data, so its usage should only be in
383-
* restricted modes.
384-
*
385-
* @param parentDocumentId the directory to return children for.
386-
* @param projection list of {@link Document} columns to put into the
387-
* cursor. If {@code null} all supported columns should be
388-
* included.
389-
* @param sortOrder how to order the rows, formatted as an SQL
390-
* {@code ORDER BY} clause (excluding the ORDER BY itself).
391-
* Passing {@code null} will use the default sort order, which
392-
* may be unordered. This ordering is a hint that can be used to
393-
* prioritize how data is fetched from the network, but UI may
394-
* always enforce a specific ordering
395-
* @throws FileNotFoundException when parent document doesn't exist or query fails
378+
* WARNING: this method should really be {@code final}, but for the backward compatibility it's
379+
* not; new classes that extend {@link FileSystemProvider} should override
380+
* {@link #queryChildDocuments(String, String[], String, boolean)}, not this method.
396381
*/
397-
protected Cursor queryChildDocumentsShowAll(
398-
String parentDocumentId, String[] projection, String sortOrder)
382+
@Override
383+
public Cursor queryChildDocuments(String documentId, String[] projection, String sortOrder)
399384
throws FileNotFoundException {
400-
return queryChildDocuments(parentDocumentId, projection, sortOrder, File -> true);
385+
return queryChildDocuments(documentId, projection, sortOrder, /* includeHidden */ false);
401386
}
402387

388+
/**
389+
* This method is similar to {@link #queryChildDocuments(String, String[], String)}, however, it
390+
* could return <b>all</b> content of the directory, <b>including restricted (hidden)
391+
* directories and files</b>.
392+
* <p>
393+
* In the scoped storage world, some directories and files (e.g. {@code Android/data/} and
394+
* {@code Android/obb/} on the external storage) are hidden for privacy reasons.
395+
* Hence, this method may reveal privacy-sensitive data, thus should be used with extra care.
396+
*/
403397
@Override
404-
public Cursor queryChildDocuments(
405-
String parentDocumentId, String[] projection, String sortOrder)
406-
throws FileNotFoundException {
407-
// Access to some directories is hidden for privacy reasons.
408-
return queryChildDocuments(parentDocumentId, projection, sortOrder, this::shouldShow);
398+
public final Cursor queryChildDocumentsForManage(String documentId, String[] projection,
399+
String sortOrder) throws FileNotFoundException {
400+
return queryChildDocuments(documentId, projection, sortOrder, /* includeHidden */ true);
409401
}
410402

411-
private Cursor queryChildDocuments(
412-
String parentDocumentId, String[] projection, String sortOrder,
413-
@NonNull Predicate<File> filter) throws FileNotFoundException {
414-
final File parent = getFileForDocId(parentDocumentId);
403+
protected Cursor queryChildDocuments(String documentId, String[] projection, String sortOrder,
404+
boolean includeHidden) throws FileNotFoundException {
405+
final File parent = getFileForDocId(documentId);
415406
final MatrixCursor result = new DirectoryCursor(
416-
resolveProjection(projection), parentDocumentId, parent);
407+
resolveProjection(projection), documentId, parent);
408+
409+
if (!parent.isDirectory()) {
410+
Log.w(TAG, '"' + documentId + "\" is not a directory");
411+
return result;
412+
}
417413

418-
if (!filter.test(parent)) {
419-
Log.w(TAG, "No permission to access parentDocumentId: " + parentDocumentId);
414+
if (!includeHidden && shouldHideDocument(documentId)) {
415+
Log.w(TAG, "Queried directory \"" + documentId + "\" is hidden");
420416
return result;
421417
}
422418

423-
if (parent.isDirectory()) {
424-
for (File file : FileUtils.listFilesOrEmpty(parent)) {
425-
if (filter.test(file)) {
426-
includeFile(result, null, file);
427-
}
428-
}
429-
} else {
430-
Log.w(TAG, "parentDocumentId '" + parentDocumentId + "' is not Directory");
419+
for (File file : FileUtils.listFilesOrEmpty(parent)) {
420+
if (!includeHidden && shouldHideDocument(file)) continue;
421+
422+
includeFile(result, null, file);
431423
}
424+
432425
return result;
433426
}
434427

@@ -450,23 +443,29 @@ private Cursor queryChildDocuments(
450443
*
451444
* @see ContentResolver#EXTRA_HONORED_ARGS
452445
*/
453-
protected final Cursor querySearchDocuments(
454-
File folder, String[] projection, Set<String> exclusion, Bundle queryArgs)
455-
throws FileNotFoundException {
446+
protected final Cursor querySearchDocuments(File folder, String[] projection,
447+
Set<String> exclusion, Bundle queryArgs) throws FileNotFoundException {
456448
final MatrixCursor result = new MatrixCursor(resolveProjection(projection));
457-
final LinkedList<File> pending = new LinkedList<>();
458-
pending.add(folder);
459-
while (!pending.isEmpty() && result.getCount() < 24) {
460-
final File file = pending.removeFirst();
461-
if (shouldHide(file)) continue;
449+
450+
// We'll be a running a BFS here.
451+
final Queue<File> pending = new ArrayDeque<>();
452+
pending.offer(folder);
453+
454+
while (!pending.isEmpty() && result.getCount() < MAX_RESULTS_NUMBER) {
455+
final File file = pending.poll();
456+
457+
// Skip hidden documents (both files and directories)
458+
if (shouldHideDocument(file)) continue;
462459

463460
if (file.isDirectory()) {
464461
for (File child : FileUtils.listFilesOrEmpty(file)) {
465-
pending.add(child);
462+
pending.offer(child);
466463
}
467464
}
468-
if (!exclusion.contains(file.getAbsolutePath()) && matchSearchQueryArguments(file,
469-
queryArgs)) {
465+
466+
if (exclusion.contains(file.getAbsolutePath())) continue;
467+
468+
if (matchSearchQueryArguments(file, queryArgs)) {
470469
includeFile(result, null, file);
471470
}
472471
}
@@ -610,26 +609,23 @@ protected RowBuilder includeFile(final MatrixCursor result, String docId, File f
610609

611610
final int flagIndex = ArrayUtils.indexOf(columns, Document.COLUMN_FLAGS);
612611
if (flagIndex != -1) {
612+
final boolean isDir = mimeType.equals(Document.MIME_TYPE_DIR);
613613
int flags = 0;
614614
if (file.canWrite()) {
615-
if (mimeType.equals(Document.MIME_TYPE_DIR)) {
615+
flags |= Document.FLAG_SUPPORTS_DELETE;
616+
flags |= Document.FLAG_SUPPORTS_RENAME;
617+
flags |= Document.FLAG_SUPPORTS_MOVE;
618+
if (isDir) {
616619
flags |= Document.FLAG_DIR_SUPPORTS_CREATE;
617-
flags |= Document.FLAG_SUPPORTS_DELETE;
618-
flags |= Document.FLAG_SUPPORTS_RENAME;
619-
flags |= Document.FLAG_SUPPORTS_MOVE;
620-
621-
if (shouldBlockFromTree(docId)) {
622-
flags |= Document.FLAG_DIR_BLOCKS_OPEN_DOCUMENT_TREE;
623-
}
624-
625620
} else {
626621
flags |= Document.FLAG_SUPPORTS_WRITE;
627-
flags |= Document.FLAG_SUPPORTS_DELETE;
628-
flags |= Document.FLAG_SUPPORTS_RENAME;
629-
flags |= Document.FLAG_SUPPORTS_MOVE;
630622
}
631623
}
632624

625+
if (isDir && shouldBlockDirectoryFromTree(docId)) {
626+
flags |= Document.FLAG_DIR_BLOCKS_OPEN_DOCUMENT_TREE;
627+
}
628+
633629
if (mimeType.startsWith("image/")) {
634630
flags |= Document.FLAG_SUPPORTS_THUMBNAIL;
635631
}
@@ -662,22 +658,36 @@ protected RowBuilder includeFile(final MatrixCursor result, String docId, File f
662658
return row;
663659
}
664660

665-
private static final Pattern PATTERN_HIDDEN_PATH = Pattern.compile(
666-
"(?i)^/storage/[^/]+/(?:[0-9]+/)?Android/(?:data|obb|sandbox)$");
667-
668661
/**
669-
* In a scoped storage world, access to "Android/data" style directories are
670-
* hidden for privacy reasons.
662+
* Some providers may want to restrict access to certain directories and files,
663+
* e.g. <i>"Android/data"</i> and <i>"Android/obb"</i> on the shared storage for
664+
* privacy reasons.
665+
* Such providers should override this method.
671666
*/
672-
protected boolean shouldHide(@NonNull File file) {
673-
return (PATTERN_HIDDEN_PATH.matcher(file.getAbsolutePath()).matches());
667+
protected boolean shouldHideDocument(@NonNull String documentId)
668+
throws FileNotFoundException {
669+
return false;
674670
}
675671

676-
private boolean shouldShow(@NonNull File file) {
677-
return !shouldHide(file);
672+
/**
673+
* A variant of the {@link #shouldHideDocument(String)} that takes a {@link File} instead of
674+
* a {@link String} {@code documentId}.
675+
*
676+
* @see #shouldHideDocument(String)
677+
*/
678+
protected final boolean shouldHideDocument(@NonNull File document)
679+
throws FileNotFoundException {
680+
return shouldHideDocument(getDocIdForFile(document));
678681
}
679682

680-
protected boolean shouldBlockFromTree(@NonNull String docId) {
683+
/**
684+
* @return if the directory that should be blocked from being selected when the user launches
685+
* an {@link Intent#ACTION_OPEN_DOCUMENT_TREE} intent.
686+
*
687+
* @see Document#FLAG_DIR_BLOCKS_OPEN_DOCUMENT_TREE
688+
*/
689+
protected boolean shouldBlockDirectoryFromTree(@NonNull String documentId)
690+
throws FileNotFoundException {
681691
return false;
682692
}
683693

core/proto/android/server/activitymanagerservice.proto

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,7 @@ message ConnectionRecordProto {
524524
DEAD = 15;
525525
NOT_PERCEPTIBLE = 16;
526526
INCLUDE_CAPABILITIES = 17;
527+
DENY_ACTIVITY_STARTS_PRE_34 = 18;
527528
}
528529
repeated Flag flags = 3;
529530
optional string service_name = 4;

media/java/android/media/AudioDeviceAttributes.java

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ public final class AudioDeviceAttributes implements Parcelable {
6868
/**
6969
* The unique address of the device. Some devices don't have addresses, only an empty string.
7070
*/
71-
private final @NonNull String mAddress;
71+
private @NonNull String mAddress;
7272
/**
7373
* The non-unique name of the device. Some devices don't have names, only an empty string.
7474
* Should not be used as a unique identifier for a device.
@@ -186,6 +186,21 @@ public AudioDeviceAttributes(int nativeType, @NonNull String address, @NonNull S
186186
mAudioDescriptors = new ArrayList<>();
187187
}
188188

189+
/**
190+
* @hide
191+
* Copy Constructor.
192+
* @param ada the copied AudioDeviceAttributes
193+
*/
194+
public AudioDeviceAttributes(AudioDeviceAttributes ada) {
195+
mRole = ada.getRole();
196+
mType = ada.getType();
197+
mAddress = ada.getAddress();
198+
mName = ada.getName();
199+
mNativeType = ada.getInternalType();
200+
mAudioProfiles = ada.getAudioProfiles();
201+
mAudioDescriptors = ada.getAudioDescriptors();
202+
}
203+
189204
/**
190205
* @hide
191206
* Returns the role of a device
@@ -216,6 +231,15 @@ public AudioDeviceAttributes(int nativeType, @NonNull String address, @NonNull S
216231
return mAddress;
217232
}
218233

234+
/**
235+
* @hide
236+
* Sets the device address. Only used by audio service.
237+
*/
238+
public void setAddress(@NonNull String address) {
239+
Objects.requireNonNull(address);
240+
mAddress = address;
241+
}
242+
219243
/**
220244
* @hide
221245
* Returns the name of the audio device, or an empty string for devices without one

0 commit comments

Comments
 (0)