summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--perfetto_config.pbtx87
-rw-r--r--src/com/android/providers/media/DatabaseHelper.java25
-rw-r--r--src/com/android/providers/media/MediaProvider.java40
-rw-r--r--src/com/android/providers/media/MediaService.java2
-rw-r--r--src/com/android/providers/media/photopicker/PickerDataLayer.java86
-rw-r--r--src/com/android/providers/media/photopicker/PickerSyncController.java287
-rw-r--r--src/com/android/providers/media/photopicker/data/PickerDbFacade.java10
-rw-r--r--src/com/android/providers/media/scan/ModernMediaScanner.java20
-rw-r--r--src/com/android/providers/media/util/DatabaseUtils.java5
-rw-r--r--src/com/android/providers/media/util/SpecialFormatDetector.java4
-rw-r--r--src/com/android/providers/media/util/XAttrUtils.java2
-rwxr-xr-xtrace.sh4
12 files changed, 392 insertions, 180 deletions
diff --git a/perfetto_config.pbtx b/perfetto_config.pbtx
new file mode 100644
index 000000000..ee6395d7d
--- /dev/null
+++ b/perfetto_config.pbtx
@@ -0,0 +1,87 @@
+buffers: {
+ size_kb: 63488
+ fill_policy: DISCARD
+}
+buffers: {
+ size_kb: 2048
+ fill_policy: DISCARD
+}
+
+data_sources: {
+ config {
+ name: "linux.ftrace"
+
+ # See: https://perfetto.dev/docs/data-sources/atrace#traceconfig
+ ftrace_config {
+ ftrace_events: "ftrace/print"
+
+ # Trace all ContentProvider commands and SQLite queries.
+ # See: https://source.corp.google.com/android-internal/frameworks/base/core/java/android/os/Trace.java?q=TRACE_TAG_DATABASE
+ # See: https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/database/sqlite/SQLiteConnection.java
+ # Uncomment to enable. Note: on a userdebug build it will add a trace for every SQLite
+ # command any application runs, which will make a trace very "noisy".
+ # atrace_categories: "database"
+
+ # Trace Binder IPC transactions.
+ # Uncomment to enable. Note: on a userdebug build it will add a trace for every Binder
+ # transaction for every application, which will make a trace very "noisy".
+ # atrace_categories: "binder_driver"
+
+ # ActivityManager, WindowManager, Graphics, View System.
+ # Uncomment to enable. Note: on a userdebug build it will traces form corresponding
+ # category for every application, which will make a trace very "noisy".
+ # atrace_categories: "wm"
+ # atrace_categories: "am"
+ # atrace_categories: "gfx"
+ # atrace_categories: "view"
+
+ # Trace MediaProviders' events.
+ atrace_apps: "com.android.providers.media.module"
+ atrace_apps: "com.google.android.providers.media.module"
+
+ # Trace Google Photos' events.
+ # Uncomment to enable.
+ # atrace_apps: "com.google.android.apps.photos"
+
+ # Trace all apps' events.
+ # Uncomment to enable.
+ # atrace_apps: "*"
+ }
+ }
+}
+
+# Android Logcat
+data_sources: {
+ config {
+ name: "android.log"
+ android_log_config {
+ min_prio: PRIO_VERBOSE # Default: PRIO_DEBUG
+
+ # If filter_tags non-empty ignores all log messages whose tag doesn't match one of the
+ # specified values.
+ # filter_tags: "MediaProvider"
+ # filter_tags: "PickerDataLayer"
+ # filter_tags: "PickerDbFacade"
+ # filter_tags: "PickerSyncController"
+
+ log_ids: LID_EVENTS
+ log_ids: LID_CRASH
+ log_ids: LID_KERNEL
+ log_ids: LID_DEFAULT
+ log_ids: LID_RADIO
+ log_ids: LID_SECURITY
+ log_ids: LID_STATS
+ log_ids: LID_SYSTEM
+ }
+ }
+}
+
+# This is for getting Thread<>Process associations and full process names.
+data_sources: {
+ config {
+ name: "linux.process_stats"
+ }
+}
+
+# Max duration: 1 min
+duration_ms: 60000
diff --git a/src/com/android/providers/media/DatabaseHelper.java b/src/com/android/providers/media/DatabaseHelper.java
index d2dd12a29..1a4b04f68 100644
--- a/src/com/android/providers/media/DatabaseHelper.java
+++ b/src/com/android/providers/media/DatabaseHelper.java
@@ -370,7 +370,7 @@ public class DatabaseHelper extends SQLiteOpenHelper implements AutoCloseable {
.setIsPending(isPending)
.setPath(path)
.build();
- Trace.beginSection("_INSERT");
+ Trace.beginSection(traceSectionName("_INSERT"));
try {
mFilesListener.onInsert(DatabaseHelper.this, insertedRow);
} finally {
@@ -424,7 +424,7 @@ public class DatabaseHelper extends SQLiteOpenHelper implements AutoCloseable {
.setOwnerPackageName(newOwnerPackage)
.build();
- Trace.beginSection("_UPDATE");
+ Trace.beginSection(traceSectionName("_UPDATE"));
try {
mFilesListener.onUpdate(DatabaseHelper.this, oldRow, newRow);
} finally {
@@ -451,7 +451,7 @@ public class DatabaseHelper extends SQLiteOpenHelper implements AutoCloseable {
.setOwnerPackageName(ownerPackage)
.setPath(path)
.build();
- Trace.beginSection("_DELETE");
+ Trace.beginSection(traceSectionName("_DELETE"));
try {
mFilesListener.onDelete(DatabaseHelper.this, deletedRow);
} finally {
@@ -462,7 +462,7 @@ public class DatabaseHelper extends SQLiteOpenHelper implements AutoCloseable {
});
db.setCustomScalarFunction("_GET_ID", (arg) -> {
if (mIdGenerator != null && !mSchemaLock.isWriteLockedByCurrentThread()) {
- Trace.beginSection("_GET_ID");
+ Trace.beginSection(traceSectionName("_GET_ID"));
try {
return mIdGenerator.apply(arg);
} finally {
@@ -696,11 +696,13 @@ public class DatabaseHelper extends SQLiteOpenHelper implements AutoCloseable {
}
public void beginTransaction() {
- Trace.beginSection("transaction " + getDatabaseName());
- Trace.beginSection("beginTransaction");
+ Trace.beginSection(traceSectionName("transaction"));
+ Trace.beginSection(traceSectionName("beginTransaction"));
try {
beginTransactionInternal();
} finally {
+ // Only end the "beginTransaction" section. We'll end the "transaction" section in
+ // endTransaction().
Trace.endSection();
}
}
@@ -729,11 +731,12 @@ public class DatabaseHelper extends SQLiteOpenHelper implements AutoCloseable {
}
public void endTransaction() {
- Trace.beginSection("endTransaction");
+ Trace.beginSection(traceSectionName("endTransaction"));
try {
endTransactionInternal();
} finally {
Trace.endSection();
+ // End "transaction" section, which we started in beginTransaction().
Trace.endSection();
}
}
@@ -860,7 +863,7 @@ public class DatabaseHelper extends SQLiteOpenHelper implements AutoCloseable {
}
private void notifySingleChangeInternal(@NonNull Uri uri, int flags) {
- Trace.beginSection("notifySingleChange");
+ Trace.beginSection(traceSectionName("notifySingleChange"));
try {
mContext.getContentResolver().notifyChange(uri, null, flags);
} finally {
@@ -869,7 +872,7 @@ public class DatabaseHelper extends SQLiteOpenHelper implements AutoCloseable {
}
private void notifyChangeInternal(@NonNull Collection<Uri> uris, int flags) {
- Trace.beginSection("notifyChange");
+ Trace.beginSection(traceSectionName("notifyChange"));
try {
for (List<Uri> partition : Iterables.partition(uris, NOTIFY_BATCH_SIZE)) {
mContext.getContentResolver().notifyChange(partition, null, flags);
@@ -2398,4 +2401,8 @@ public class DatabaseHelper extends SQLiteOpenHelper implements AutoCloseable {
boolean isDatabaseRecovering() {
return mIsRecovering.get();
}
+
+ private String traceSectionName(@NonNull String method) {
+ return "DH[" + getDatabaseName() + "]." + method;
+ }
}
diff --git a/src/com/android/providers/media/MediaProvider.java b/src/com/android/providers/media/MediaProvider.java
index 6684f4741..7967399f4 100644
--- a/src/com/android/providers/media/MediaProvider.java
+++ b/src/com/android/providers/media/MediaProvider.java
@@ -688,7 +688,7 @@ public class MediaProvider extends ContentProvider {
}
private final void updateQuotaTypeForUri(@NonNull Uri uri, int mediaType) {
- Trace.beginSection("updateQuotaTypeForUri");
+ Trace.beginSection("MP.updateQuotaTypeForUri");
File file;
try {
file = queryForDataFile(uri, null);
@@ -824,7 +824,7 @@ public class MediaProvider extends ContentProvider {
helper.postBackground(() -> {
// Item no longer exists, so revoke all access to it
- Trace.beginSection("revokeUriPermission");
+ Trace.beginSection("MP.revokeUriPermission");
try {
acceptWithExpansion((uri) -> {
getContext().revokeUriPermission(uri, ~0);
@@ -3372,7 +3372,7 @@ public class MediaProvider extends ContentProvider {
private Cursor query(Uri uri, String[] projection, Bundle queryArgs,
CancellationSignal signal, boolean forSelf) {
- Trace.beginSection("query");
+ Trace.beginSection("MP.query [" + uri + ']');
try {
return queryInternal(uri, projection, queryArgs, signal, forSelf);
} catch (FallbackException e) {
@@ -3733,7 +3733,7 @@ public class MediaProvider extends ContentProvider {
private void ensureFileColumns(int match, @NonNull Uri uri, @NonNull Bundle extras,
@NonNull ContentValues values, boolean makeUnique, @Nullable String currentPath)
throws VolumeArgumentException, VolumeNotFoundException {
- Trace.beginSection("ensureFileColumns");
+ Trace.beginSection("MP.ensureFileColumns");
Objects.requireNonNull(uri);
Objects.requireNonNull(extras);
@@ -4272,7 +4272,7 @@ public class MediaProvider extends ContentProvider {
}
private int bulkInsertPlaylist(@NonNull Uri uri, @NonNull ContentValues[] values) {
- Trace.beginSection("bulkInsertPlaylist");
+ Trace.beginSection("MP.bulkInsertPlaylist");
try {
try {
return addPlaylistMembers(uri, values);
@@ -4783,7 +4783,7 @@ public class MediaProvider extends ContentProvider {
@Override
public @Nullable Uri insert(@NonNull Uri uri, @Nullable ContentValues values,
@Nullable Bundle extras) {
- Trace.beginSection("insert");
+ Trace.beginSection("MP.insert [" + uri + ']');
try {
try {
return insertInternal(uri, values, extras);
@@ -5256,7 +5256,7 @@ public class MediaProvider extends ContentProvider {
*/
private @NonNull SQLiteQueryBuilder getQueryBuilder(int type, int match,
@NonNull Uri uri, @NonNull Bundle extras, @Nullable Consumer<String> honored) {
- Trace.beginSection("getQueryBuilder");
+ Trace.beginSection("MP.getQueryBuilder");
try {
return getQueryBuilderInternal(type, match, uri, extras, honored);
} finally {
@@ -5898,7 +5898,7 @@ public class MediaProvider extends ContentProvider {
@Override
public int delete(@NonNull Uri uri, @Nullable Bundle extras) {
- Trace.beginSection("delete");
+ Trace.beginSection("MP.delete [" + uri + ']');
try {
return deleteInternal(uri, extras);
} catch (FallbackException e) {
@@ -6243,7 +6243,7 @@ public class MediaProvider extends ContentProvider {
@Override
public Bundle call(String method, String arg, Bundle extras) {
- Trace.beginSection("call");
+ Trace.beginSection("MP.call [" + method + ']');
try {
return callInternal(method, arg, extras);
} finally {
@@ -6941,7 +6941,7 @@ public class MediaProvider extends ContentProvider {
}
private void invalidateThumbnails(Uri uri) {
- Trace.beginSection("invalidateThumbnails");
+ Trace.beginSection("MP.invalidateThumbnails");
try {
invalidateThumbnailsInternal(uri);
} finally {
@@ -6997,7 +6997,7 @@ public class MediaProvider extends ContentProvider {
@Override
public int update(@NonNull Uri uri, @Nullable ContentValues values,
@Nullable Bundle extras) {
- Trace.beginSection("update");
+ Trace.beginSection("MP.update [" + uri + ']');
try {
return updateInternal(uri, values, extras);
} catch (FallbackException e) {
@@ -7170,7 +7170,7 @@ public class MediaProvider extends ContentProvider {
}
if (!isCallingPackageSelf()) {
- Trace.beginSection("filter");
+ Trace.beginSection("MP.filter");
// We default to filtering mutable columns, except when we know
// the single item being updated is pending; when it's finally
@@ -7275,7 +7275,7 @@ public class MediaProvider extends ContentProvider {
&& !initialValues.containsKey(MediaColumns.DATA)
&& !isThumbnail
&& allowMovement) {
- Trace.beginSection("movement");
+ Trace.beginSection("MP.movement");
// We only support movement under well-defined collections
switch (match) {
@@ -7401,7 +7401,7 @@ public class MediaProvider extends ContentProvider {
// it's applied, we need to snapshot affected IDs here
final LongArray updatedIds = new LongArray();
if (triggerInvalidate || triggerScan) {
- Trace.beginSection("snapshot");
+ Trace.beginSection("MP.snapshot");
final LocalCallingIdentity token = clearLocalCallingIdentity();
try (Cursor c = qb.query(helper, new String[] { FileColumns._ID },
userWhere, userWhereArgs, null, null, null, null, null)) {
@@ -7468,7 +7468,7 @@ public class MediaProvider extends ContentProvider {
// If the caller tried (and failed) to update metadata, the file on disk
// might have changed, to scan it to collect the latest metadata.
if (triggerInvalidate || triggerScan) {
- Trace.beginSection("invalidate");
+ Trace.beginSection("MP.invalidate");
final LocalCallingIdentity token = clearLocalCallingIdentity();
try {
for (int i = 0; i < updatedIds.size(); i++) {
@@ -7641,7 +7641,7 @@ public class MediaProvider extends ContentProvider {
* that the playlist entry is retained to avoid user data loss.
*/
private void resolvePlaylistMembers(@NonNull Uri playlistUri) {
- Trace.beginSection("resolvePlaylistMembers");
+ Trace.beginSection("MP.resolvePlaylistMembers");
try {
final DatabaseHelper helper;
try {
@@ -8103,7 +8103,7 @@ public class MediaProvider extends ContentProvider {
final boolean allowHidden = isCallingPackageAllowedHidden();
final int match = matchUri(uri, allowHidden);
- Trace.beginSection("ensureThumbnail");
+ Trace.beginSection("MP.ensureThumbnail");
final LocalCallingIdentity token = clearLocalCallingIdentity();
try {
switch (match) {
@@ -8969,7 +8969,7 @@ public class MediaProvider extends ContentProvider {
final LongArray res = new LongArray();
final LongArray freeOffsets = new LongArray();
- Trace.beginSection("getRedactionRanges");
+ Trace.beginSection("MP.getRedactionRanges");
try {
if (ExifInterface.isSupportedMimeType(mimeType)) {
final ExifInterface exif = new ExifInterface(fis.getFD());
@@ -9019,7 +9019,7 @@ public class MediaProvider extends ContentProvider {
private FileAccessAttributes queryForFileAttributes(final String path)
throws FileNotFoundException {
- Trace.beginSection("queryFileAttr");
+ Trace.beginSection("MP.queryFileAttr");
final Uri contentUri = FileUtils.getContentUriForPath(path);
final String[] projection = new String[]{
MediaColumns._ID,
@@ -9950,7 +9950,7 @@ public class MediaProvider extends ContentProvider {
*/
private void enforceCallingPermission(@NonNull Uri uri, @NonNull Bundle extras,
boolean forWrite) {
- Trace.beginSection("enforceCallingPermission");
+ Trace.beginSection("MP.enforceCallingPermission");
try {
enforceCallingPermissionInternal(uri, extras, forWrite);
} finally {
diff --git a/src/com/android/providers/media/MediaService.java b/src/com/android/providers/media/MediaService.java
index c376bc3fd..690114d67 100644
--- a/src/com/android/providers/media/MediaService.java
+++ b/src/com/android/providers/media/MediaService.java
@@ -64,7 +64,7 @@ public class MediaService extends JobIntentService {
@Override
protected void onHandleWork(Intent intent) {
- Trace.beginSection(intent.getAction());
+ Trace.beginSection("MediaService.handle[" + intent.getAction() + ']');
if (Log.isLoggable(TAG, Log.INFO)) {
Log.i(TAG, "Begin " + intent);
}
diff --git a/src/com/android/providers/media/photopicker/PickerDataLayer.java b/src/com/android/providers/media/photopicker/PickerDataLayer.java
index 217a79913..ea4067a5e 100644
--- a/src/com/android/providers/media/photopicker/PickerDataLayer.java
+++ b/src/com/android/providers/media/photopicker/PickerDataLayer.java
@@ -17,6 +17,8 @@
package com.android.providers.media.photopicker;
import static android.provider.CloudMediaProviderContract.METHOD_GET_MEDIA_COLLECTION_INFO;
+import static android.provider.CloudMediaProviderContract.MediaCollectionInfo.ACCOUNT_CONFIGURATION_INTENT;
+import static android.provider.CloudMediaProviderContract.MediaCollectionInfo.ACCOUNT_NAME;
import static com.android.providers.media.PickerUriResolver.getAlbumUri;
import static com.android.providers.media.PickerUriResolver.getMediaCollectionInfoUri;
@@ -26,11 +28,14 @@ import android.content.Intent;
import android.database.Cursor;
import android.database.MergeCursor;
import android.os.Bundle;
-import android.provider.CloudMediaProviderContract;
+import android.os.Trace;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.util.Log;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
import com.android.providers.media.photopicker.data.CloudProviderQueryExtras;
import com.android.providers.media.photopicker.data.PickerDbFacade;
@@ -59,8 +64,18 @@ public class PickerDataLayer {
public Cursor fetchMedia(Bundle queryArgs) {
final CloudProviderQueryExtras queryExtras
= CloudProviderQueryExtras.fromMediaStoreBundle(queryArgs, mLocalProvider);
- final String albumId = queryExtras.getAlbumId();
final String authority = queryExtras.getAlbumAuthority();
+
+ Trace.beginSection(traceSectionName("fetchMedia", authority));
+ try {
+ return fetchMediaInternal(authority, queryExtras);
+ } finally {
+ Trace.endSection();
+ }
+ }
+
+ private Cursor fetchMediaInternal(String authority, CloudProviderQueryExtras queryExtras) {
+ final String albumId = queryExtras.getAlbumId();
// Use media table for all media except albums. Merged categories like,
// favorites and video are tagged in the media table and are not a part of
// album_media.
@@ -99,6 +114,15 @@ public class PickerDataLayer {
}
public Cursor fetchAlbums(Bundle queryArgs) {
+ Trace.beginSection(traceSectionName("fetchAlbums"));
+ try {
+ return fetchAlbumsInternal(queryArgs);
+ } finally {
+ Trace.endSection();
+ }
+ }
+
+ private Cursor fetchAlbumsInternal(Bundle queryArgs) {
// Refresh the 'media' table so that 'merged' albums (Favorites and Videos) are up to date
mSyncController.syncAllMedia();
@@ -136,37 +160,54 @@ public class PickerDataLayer {
return mergeCursor;
}
+ @Nullable
public AccountInfo fetchCloudAccountInfo() {
final String cloudProvider = mDbFacade.getCloudProvider();
if (cloudProvider == null) {
return null;
}
+ Trace.beginSection(traceSectionName("fetchCloudAccountInfo"));
try {
- final Bundle accountBundle = mContext.getContentResolver().call(
- getMediaCollectionInfoUri(cloudProvider), METHOD_GET_MEDIA_COLLECTION_INFO,
- /* arg */ null, /* extras */ null);
- final String accountName = accountBundle.getString(
- CloudMediaProviderContract.MediaCollectionInfo.ACCOUNT_NAME);
- final Intent configIntent = (Intent) accountBundle.getParcelable(
- CloudMediaProviderContract.MediaCollectionInfo.ACCOUNT_CONFIGURATION_INTENT);
-
- if (accountName == null) {
- return null;
- }
-
- return new AccountInfo(accountName, configIntent);
+ return fetchCloudAccountInfoInternal(cloudProvider);
} catch (Exception e) {
Log.w(TAG, "Failed to fetch account info from cloud provider: " + cloudProvider, e);
return null;
+ } finally {
+ Trace.endSection();
+ }
+ }
+
+ @Nullable
+ public AccountInfo fetchCloudAccountInfoInternal(@NonNull String cloudProvider) {
+ final Bundle accountBundle = mContext.getContentResolver()
+ .call(getMediaCollectionInfoUri(cloudProvider), METHOD_GET_MEDIA_COLLECTION_INFO,
+ /* arg */ null, /* extras */ null);
+
+ final String accountName = accountBundle.getString(ACCOUNT_NAME);
+ if (accountName == null) {
+ return null;
}
+ final Intent configIntent = accountBundle.getParcelable(ACCOUNT_CONFIGURATION_INTENT);
+
+ return new AccountInfo(accountName, configIntent);
}
- private Cursor queryProviderAlbums(String authority, Bundle queryArgs) {
+ private Cursor queryProviderAlbums(@Nullable String authority, Bundle queryArgs) {
if (authority == null) {
// Can happen if there is no cloud provider
return null;
}
+
+ Trace.beginSection(traceSectionName("queryProviderAlbums", authority));
+ try {
+ return queryProviderAlbumsInternal(authority, queryArgs);
+ } finally {
+ Trace.endSection();
+ }
+ }
+
+ private Cursor queryProviderAlbumsInternal(@NonNull String authority, Bundle queryArgs) {
try {
return mContext.getContentResolver().query(getAlbumUri(authority),
/* projection */ null, queryArgs, /* cancellationSignal */ null);
@@ -180,6 +221,19 @@ public class PickerDataLayer {
return mLocalProvider.equals(authority);
}
+ private String traceSectionName(@NonNull String method) {
+ return traceSectionName(method, null);
+ }
+
+ private String traceSectionName(@NonNull String method, @Nullable String authority) {
+ final StringBuilder sb = new StringBuilder("PDL.")
+ .append(method);
+ if (authority != null) {
+ sb.append('[').append(isLocal(authority) ? "local" : "cloud").append(']');
+ }
+ return sb.toString();
+ }
+
public static class AccountInfo {
public final String accountName;
public final Intent accountConfigurationIntent;
diff --git a/src/com/android/providers/media/photopicker/PickerSyncController.java b/src/com/android/providers/media/photopicker/PickerSyncController.java
index 184e8fd48..3d0cf14b9 100644
--- a/src/com/android/providers/media/photopicker/PickerSyncController.java
+++ b/src/com/android/providers/media/photopicker/PickerSyncController.java
@@ -21,7 +21,8 @@ import static android.provider.CloudMediaProviderContract.EXTRA_ALBUM_ID;
import static android.provider.CloudMediaProviderContract.EXTRA_MEDIA_COLLECTION_ID;
import static android.provider.CloudMediaProviderContract.EXTRA_PAGE_TOKEN;
import static android.provider.CloudMediaProviderContract.EXTRA_SYNC_GENERATION;
-import static android.provider.CloudMediaProviderContract.MediaCollectionInfo;
+import static android.provider.CloudMediaProviderContract.MediaCollectionInfo.LAST_MEDIA_SYNC_GENERATION;
+import static android.provider.CloudMediaProviderContract.MediaCollectionInfo.MEDIA_COLLECTION_ID;
import static com.android.providers.media.PickerUriResolver.getDeletedMediaUri;
import static com.android.providers.media.PickerUriResolver.getMediaCollectionInfoUri;
@@ -37,6 +38,7 @@ import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Process;
+import android.os.Trace;
import android.os.storage.StorageManager;
import android.provider.CloudMediaProvider;
import android.provider.CloudMediaProviderContract;
@@ -94,7 +96,7 @@ public class PickerSyncController {
private static final int SYNC_TYPE_MEDIA_RESET = 3;
@IntDef(flag = false, prefix = { "SYNC_TYPE_" }, value = {
- SYNC_TYPE_NONE,
+ SYNC_TYPE_NONE,
SYNC_TYPE_MEDIA_INCREMENTAL,
SYNC_TYPE_MEDIA_FULL,
SYNC_TYPE_MEDIA_RESET,
@@ -160,18 +162,24 @@ public class PickerSyncController {
* Syncs the local and currently enabled cloud {@link CloudMediaProvider} instances
*/
public void syncAllMedia() {
- syncAllMediaFromProvider(mLocalProvider, /* retryOnFailure */ true);
-
- synchronized (mLock) {
- final String cloudProvider = mCloudProviderInfo.authority;
+ Trace.beginSection(traceSectionName("syncAllMedia"));
+ try {
+ syncAllMediaFromProvider(mLocalProvider, /* isLocal */ true, /* retryOnFailure */ true);
- syncAllMediaFromProvider(cloudProvider, /* retryOnFailure */ true);
+ synchronized (mLock) {
+ final String cloudProvider = mCloudProviderInfo.authority;
+ syncAllMediaFromProvider(cloudProvider, /* isLocal */ false,
+ /* retryOnFailure */ true);
- // Reset the album_media table every time we sync all media
- resetAlbumMedia();
+ // Reset the album_media table every time we sync all media
+ // TODO(sergeynv@): do we really need to reset for both providers?
+ resetAlbumMedia();
- // Set the latest cloud provider on the facade
- mDbFacade.setCloudProvider(cloudProvider);
+ // Set the latest cloud provider on the facade
+ mDbFacade.setCloudProvider(cloudProvider);
+ }
+ } finally {
+ Trace.endSection();
}
}
@@ -181,26 +189,27 @@ public class PickerSyncController {
*/
public void syncAlbumMedia(String albumId, boolean isLocal) {
if (isLocal) {
- syncAlbumMediaFromProvider(mLocalProvider, albumId);
+ syncAlbumMediaFromProvider(mLocalProvider, /* isLocal */ true, albumId);
} else {
synchronized (mLock) {
- syncAlbumMediaFromProvider(mCloudProviderInfo.authority, albumId);
+ syncAlbumMediaFromProvider(
+ mCloudProviderInfo.authority, /* isLocal */ false, albumId);
}
}
}
private void resetAlbumMedia() {
- executeSyncAlbumReset(mLocalProvider, /* albumId */ null);
+ executeSyncAlbumReset(mLocalProvider, /* isLocal */ true, /* albumId */ null);
synchronized (mLock) {
final String cloudProvider = mCloudProviderInfo.authority;
- executeSyncAlbumReset(cloudProvider, /* albumId */ null);
+ executeSyncAlbumReset(cloudProvider, /* isLocal */ false, /* albumId */ null);
}
}
- private void resetAllMedia(String authority) {
- executeSyncReset(authority);
- resetCachedMediaCollectionInfo(authority);
+ private void resetAllMedia(String authority, boolean isLocal) {
+ executeSyncReset(authority, isLocal);
+ resetCachedMediaCollectionInfo(authority, isLocal);
}
@NonNull
@@ -242,7 +251,12 @@ public class PickerSyncController {
* otherwise
*/
public boolean setCloudProvider(String authority) {
- return setCloudProviderInternal(authority, /* ignoreAllowlist */ false);
+ Trace.beginSection(traceSectionName("setCloudProvider"));
+ try {
+ return setCloudProviderInternal(authority, /* ignoreAllowlist */ false);
+ } finally {
+ Trace.endSection();
+ }
}
/**
@@ -250,7 +264,12 @@ public class PickerSyncController {
*/
@VisibleForTesting
public void forceSetCloudProvider(String authority) {
- setCloudProviderInternal(authority, /* ignoreAllowlist */ true);
+ Trace.beginSection(traceSectionName("forceSetCloudProvider"));
+ try {
+ setCloudProviderInternal(authority, /* ignoreAllowlist */ true);
+ } finally {
+ Trace.endSection();
+ }
}
private boolean setCloudProviderInternal(String authority, boolean ignoreAllowList) {
@@ -266,7 +285,7 @@ public class PickerSyncController {
synchronized (mLock) {
final String oldAuthority = mCloudProviderInfo.authority;
persistCloudProviderInfo(newProviderInfo);
- resetCachedMediaCollectionInfo(newProviderInfo.authority);
+ resetCachedMediaCollectionInfo(newProviderInfo.authority, /* isLocal */ false);
// Disable cloud provider queries on the db until next sync
// This will temporarily *clear* the cloud provider on the db facade and prevent
@@ -435,55 +454,60 @@ public class PickerSyncController {
editor.apply();
}
- private void syncAlbumMediaFromProvider(String authority, String albumId) {
+ private void syncAlbumMediaFromProvider(String authority, boolean isLocal, String albumId) {
final Bundle queryArgs = new Bundle();
queryArgs.putString(EXTRA_ALBUM_ID, albumId);
+ Trace.beginSection(traceSectionName("syncAlbumMediaFromProvider", isLocal));
try {
- executeSyncAlbumReset(authority, albumId);
+ executeSyncAlbumReset(authority, isLocal, albumId);
if (authority != null) {
- executeSyncAddAlbum(authority, albumId, queryArgs);
+ executeSyncAddAlbum(authority, isLocal, albumId, queryArgs);
}
} catch (RuntimeException e) {
// Unlike syncAllMediaFromProvider, we don't retry here because any errors would have
// occurred in fetching all the album_media since incremental sync is not supported.
// A full sync is therefore unlikely to resolve any issue
Log.e(TAG, "Failed to sync album media", e);
+ } finally {
+ Trace.endSection();
}
}
- private void syncAllMediaFromProvider(String authority, boolean retryOnFailure) {
+ private void syncAllMediaFromProvider(String authority, boolean isLocal,
+ boolean retryOnFailure) {
+ Trace.beginSection(traceSectionName("syncAllMediaFromProvider", isLocal));
try {
- final SyncRequestParams params = getSyncRequestParams(authority);
+ final SyncRequestParams params = getSyncRequestParams(authority, isLocal);
switch (params.syncType) {
case SYNC_TYPE_MEDIA_RESET:
// Can only happen when |authority| has been set to null and we need to clean up
- resetAllMedia(authority);
+ resetAllMedia(authority, isLocal);
break;
case SYNC_TYPE_MEDIA_FULL:
- resetAllMedia(authority);
+ resetAllMedia(authority, isLocal);
// Pass a mutable empty bundle intentionally because it might be populated with
// the next page token as part of a query to a cloud provider supporting
// pagination
- executeSyncAdd(authority, params.getMediaCollectionId(),
+ executeSyncAdd(authority, isLocal, params.getMediaCollectionId(),
/* isIncrementalSync */ false, /* queryArgs */ new Bundle());
// Commit sync position
- cacheMediaCollectionInfo(authority, params.latestMediaCollectionInfo);
+ cacheMediaCollectionInfo(authority, isLocal, params.latestMediaCollectionInfo);
break;
case SYNC_TYPE_MEDIA_INCREMENTAL:
final Bundle queryArgs = new Bundle();
queryArgs.putLong(EXTRA_SYNC_GENERATION, params.syncGeneration);
- executeSyncAdd(authority, params.getMediaCollectionId(),
+ executeSyncAdd(authority, isLocal, params.getMediaCollectionId(),
/* isIncrementalSync */ true, queryArgs);
- executeSyncRemove(authority, params.getMediaCollectionId(), queryArgs);
+ executeSyncRemove(authority, isLocal, params.getMediaCollectionId(), queryArgs);
// Commit sync position
- cacheMediaCollectionInfo(authority, params.latestMediaCollectionInfo);
+ cacheMediaCollectionInfo(authority, isLocal, params.latestMediaCollectionInfo);
break;
case SYNC_TYPE_NONE:
break;
@@ -492,33 +516,40 @@ public class PickerSyncController {
}
} catch (RuntimeException e) {
// Reset all media for the cloud provider in case it never succeeds
- resetAllMedia(authority);
+ resetAllMedia(authority, isLocal);
// Attempt a full sync. If this fails, the db table would have been reset,
// flushing all old content and leaving the picker UI empty.
Log.e(TAG, "Failed to sync all media. Reset media and retry: " + retryOnFailure, e);
if (retryOnFailure) {
- syncAllMediaFromProvider(authority, /* retryOnFailure */ false);
+ syncAllMediaFromProvider(authority, isLocal, /* retryOnFailure */ false);
}
+ } finally {
+ Trace.endSection();
}
}
- private void executeSyncReset(String authority) {
- Log.i(TAG, "Executing SyncReset. authority: " + authority);
+ private void executeSyncReset(String authority, boolean isLocal) {
+ Log.i(TAG, "Executing SyncReset. isLocal: " + isLocal + ". authority: " + authority);
+ Trace.beginSection(traceSectionName("executeSyncReset", isLocal));
try (PickerDbFacade.DbWriteOperation operation =
mDbFacade.beginResetMediaOperation(authority)) {
final int writeCount = operation.execute(null /* cursor */);
operation.setSuccess();
- Log.i(TAG, "SyncReset. Authority: " + authority + ". Result count: " + writeCount);
+ Log.i(TAG, "SyncReset. isLocal:" + isLocal + ". authority: " + authority
+ + ". result count: " + writeCount);
+ } finally {
+ Trace.endSection();
}
}
- private void executeSyncAlbumReset(String authority, String albumId) {
- Log.i(TAG, "Executing SyncAlbumReset. authority: " + authority + ". albumId: "
- + albumId);
+ private void executeSyncAlbumReset(String authority, boolean isLocal, String albumId) {
+ Log.i(TAG, "Executing SyncAlbumReset."
+ + " isLocal: " + isLocal + ". authority: " + authority + ". albumId: " + albumId);
+ Trace.beginSection(traceSectionName("executeSyncAlbumReset", isLocal));
try (PickerDbFacade.DbWriteOperation operation =
mDbFacade.beginResetAlbumMediaOperation(authority, albumId)) {
final int writeCount = operation.execute(null /* cursor */);
@@ -526,29 +557,39 @@ public class PickerSyncController {
Log.i(TAG, "Successfully executed SyncResetAlbum. authority: " + authority
+ ". albumId: " + albumId + ". Result count: " + writeCount);
+ } finally {
+ Trace.endSection();
}
}
- private void executeSyncAdd(String authority, String expectedMediaCollectionId,
- boolean isIncrementalSync, Bundle queryArgs) {
+ private void executeSyncAdd(String authority, boolean isLocal,
+ String expectedMediaCollectionId, boolean isIncrementalSync, Bundle queryArgs) {
final Uri uri = getMediaUri(authority);
final List<String> expectedHonoredArgs = new ArrayList<>();
if (isIncrementalSync) {
expectedHonoredArgs.add(EXTRA_SYNC_GENERATION);
}
- Log.i(TAG, "Executing SyncAdd. authority: " + authority);
+ Log.i(TAG, "Executing SyncAdd. isLocal: " + isLocal + ". authority: " + authority);
+
+ Trace.beginSection(traceSectionName("executeSyncAdd", isLocal));
try (PickerDbFacade.DbWriteOperation operation =
mDbFacade.beginAddMediaOperation(authority)) {
executePagedSync(uri, expectedMediaCollectionId, expectedHonoredArgs, queryArgs,
operation);
+ } finally {
+ Trace.endSection();
}
}
- private void executeSyncAddAlbum(String authority, String albumId, Bundle queryArgs) {
+ private void executeSyncAddAlbum(String authority, boolean isLocal,
+ String albumId, Bundle queryArgs) {
final Uri uri = getMediaUri(authority);
- Log.i(TAG, "Executing SyncAddAlbum. authority: " + authority + ". albumId: " + albumId);
+ Log.i(TAG, "Executing SyncAddAlbum. "
+ + "isLocal: " + isLocal + ". authority: " + authority + ". albumId: " + albumId);
+
+ Trace.beginSection(traceSectionName("executeSyncAddAlbum", isLocal));
try (PickerDbFacade.DbWriteOperation operation =
mDbFacade.beginAddAlbumMediaOperation(authority, albumId)) {
@@ -556,17 +597,24 @@ public class PickerSyncController {
// always a full sync
executePagedSync(uri, /* mediaCollectionId */ null, Arrays.asList(EXTRA_ALBUM_ID),
queryArgs, operation);
+ } finally {
+ Trace.endSection();
}
}
- private void executeSyncRemove(String authority, String mediaCollectionId, Bundle queryArgs) {
+ private void executeSyncRemove(String authority, boolean isLocal,
+ String mediaCollectionId, Bundle queryArgs) {
final Uri uri = getDeletedMediaUri(authority);
- Log.i(TAG, "Executing SyncRemove. authority: " + authority);
+ Log.i(TAG, "Executing SyncRemove. isLocal: " + isLocal + ". authority: " + authority);
+
+ Trace.beginSection(traceSectionName("executeSyncRemove", isLocal));
try (PickerDbFacade.DbWriteOperation operation =
mDbFacade.beginRemoveMediaOperation(authority)) {
executePagedSync(uri, mediaCollectionId, Arrays.asList(EXTRA_SYNC_GENERATION),
queryArgs, operation);
+ } finally {
+ Trace.endSection();
}
}
@@ -602,47 +650,45 @@ public class PickerSyncController {
Log.d(TAG, "Updated cloud provider to: " + authority);
}
- private void cacheMediaCollectionInfo(String authority, Bundle bundle) {
+ private void cacheMediaCollectionInfo(String authority, boolean isLocal, Bundle bundle) {
if (authority == null) {
Log.d(TAG, "Ignoring cache media info for null authority with bundle: " + bundle);
return;
}
- final SharedPreferences.Editor editor = mSyncPrefs.edit();
-
- if (bundle == null) {
- editor.remove(getPrefsKey(authority, MediaCollectionInfo.MEDIA_COLLECTION_ID));
- editor.remove(getPrefsKey(authority, MediaCollectionInfo.LAST_MEDIA_SYNC_GENERATION));
- } else {
- final String collectionId = bundle.getString(MediaCollectionInfo.MEDIA_COLLECTION_ID);
- final long generation = bundle.getLong(
- MediaCollectionInfo.LAST_MEDIA_SYNC_GENERATION);
-
- editor.putString(getPrefsKey(authority, MediaCollectionInfo.MEDIA_COLLECTION_ID),
- collectionId);
- editor.putLong(getPrefsKey(authority, MediaCollectionInfo.LAST_MEDIA_SYNC_GENERATION),
- generation);
+ Trace.beginSection(traceSectionName("cacheMediaCollectionInfo", isLocal));
+ try {
+ final SharedPreferences.Editor editor = mSyncPrefs.edit();
+ if (bundle == null) {
+ editor.remove(getPrefsKey(isLocal, MEDIA_COLLECTION_ID));
+ editor.remove(getPrefsKey(isLocal, LAST_MEDIA_SYNC_GENERATION));
+ } else {
+ final String collectionId = bundle.getString(MEDIA_COLLECTION_ID);
+ final long generation = bundle.getLong(LAST_MEDIA_SYNC_GENERATION);
+
+ editor.putString(getPrefsKey(isLocal, MEDIA_COLLECTION_ID), collectionId);
+ editor.putLong(getPrefsKey(isLocal, LAST_MEDIA_SYNC_GENERATION), generation);
+ }
+ editor.apply();
+ } finally {
+ Trace.endSection();
}
-
- editor.apply();
}
- private void resetCachedMediaCollectionInfo(String authority) {
- cacheMediaCollectionInfo(authority, /* bundle */ null);
+ private void resetCachedMediaCollectionInfo(String authority, boolean isLocal) {
+ cacheMediaCollectionInfo(authority, isLocal, /* bundle */ null);
}
- private Bundle getCachedMediaCollectionInfo(String authority) {
+ private Bundle getCachedMediaCollectionInfo(boolean isLocal) {
final Bundle bundle = new Bundle();
final String collectionId = mSyncPrefs.getString(
- getPrefsKey(authority, MediaCollectionInfo.MEDIA_COLLECTION_ID),
- /* default */ null);
+ getPrefsKey(isLocal, MEDIA_COLLECTION_ID), /* default */ null);
final long generation = mSyncPrefs.getLong(
- getPrefsKey(authority, MediaCollectionInfo.LAST_MEDIA_SYNC_GENERATION),
- /* default */ -1);
+ getPrefsKey(isLocal, LAST_MEDIA_SYNC_GENERATION), /* default */ -1);
- bundle.putString(MediaCollectionInfo.MEDIA_COLLECTION_ID, collectionId);
- bundle.putLong(MediaCollectionInfo.LAST_MEDIA_SYNC_GENERATION, generation);
+ bundle.putString(MEDIA_COLLECTION_ID, collectionId);
+ bundle.putLong(LAST_MEDIA_SYNC_GENERATION, generation);
return bundle;
}
@@ -654,27 +700,24 @@ public class PickerSyncController {
}
@SyncType
- private SyncRequestParams getSyncRequestParams(String authority) {
+ private SyncRequestParams getSyncRequestParams(String authority, boolean isLocal) {
if (authority == null) {
// Only cloud authority can be null
Log.d(TAG, "Fetching SyncRequestParams. Null cloud authority. Result: SYNC_TYPE_RESET");
return SyncRequestParams.forResetMedia();
}
- final Bundle cachedMediaCollectionInfo = getCachedMediaCollectionInfo(authority);
+ final Bundle cachedMediaCollectionInfo = getCachedMediaCollectionInfo(isLocal);
final Bundle latestMediaCollectionInfo = getLatestMediaCollectionInfo(authority);
- final String latestCollectionId =
- latestMediaCollectionInfo.getString(MediaCollectionInfo.MEDIA_COLLECTION_ID);
- final long latestGeneration =
- latestMediaCollectionInfo.getLong(MediaCollectionInfo.LAST_MEDIA_SYNC_GENERATION);
+ final String latestCollectionId = latestMediaCollectionInfo.getString(MEDIA_COLLECTION_ID);
+ final long latestGeneration = latestMediaCollectionInfo.getLong(LAST_MEDIA_SYNC_GENERATION);
- final String cachedCollectionId =
- cachedMediaCollectionInfo.getString(MediaCollectionInfo.MEDIA_COLLECTION_ID);
- final long cachedGeneration = cachedMediaCollectionInfo.getLong(
- MediaCollectionInfo.LAST_MEDIA_SYNC_GENERATION);
+ final String cachedCollectionId = cachedMediaCollectionInfo.getString(MEDIA_COLLECTION_ID);
+ final long cachedGeneration = cachedMediaCollectionInfo.getLong(LAST_MEDIA_SYNC_GENERATION);
- Log.d(TAG, "Fetching SyncRequestParams. Authority: " + authority
+ Log.d(TAG, "Fetching SyncRequestParams. Islocal: " + isLocal
+ + ". Authority: " + authority
+ ". LatestMediaCollectionInfo: " + latestMediaCollectionInfo
+ ". CachedMediaCollectionInfo: " + cachedMediaCollectionInfo);
@@ -684,26 +727,24 @@ public class PickerSyncController {
}
if (!Objects.equals(latestCollectionId, cachedCollectionId)) {
- Log.d(TAG, "SyncRequestParams. Authority: " + authority + ". Result: SYNC_TYPE_FULL");
+ Log.d(TAG, "SyncRequestParams. Islocal: " + isLocal + ". Authority: " + authority
+ + ". Result: SYNC_TYPE_FULL");
return SyncRequestParams.forFullMedia(latestMediaCollectionInfo);
}
if (cachedGeneration == latestGeneration) {
- Log.d(TAG, "SyncRequestParams. Authority: " + authority + ". Result: SYNC_TYPE_NONE");
+ Log.d(TAG, "SyncRequestParams. Islocal: " + isLocal + ". Authority: " + authority
+ + ". Result: SYNC_TYPE_NONE");
return SyncRequestParams.forNone();
}
- Log.d(TAG, "SyncRequestParams. Authority: " + authority
+ Log.d(TAG, "SyncRequestParams. Islocal: " + isLocal + ". Authority: " + authority
+ ". Result: SYNC_TYPE_INCREMENTAL");
return SyncRequestParams.forIncremental(cachedGeneration, latestMediaCollectionInfo);
}
- private String getPrefsKey(String authority, String key) {
- return (isLocal(authority) ? PREFS_KEY_LOCAL_PREFIX : PREFS_KEY_CLOUD_PREFIX) + key;
- }
-
- private boolean isLocal(String authority) {
- return mLocalProvider.equals(authority);
+ private String getPrefsKey(boolean isLocal, String key) {
+ return (isLocal ? PREFS_KEY_LOCAL_PREFIX : PREFS_KEY_CLOUD_PREFIX) + key;
}
private Cursor query(Uri uri, Bundle extras) {
@@ -714,31 +755,36 @@ public class PickerSyncController {
private void executePagedSync(Uri uri, String expectedMediaCollectionId,
List<String> expectedHonoredArgs, Bundle queryArgs,
PickerDbFacade.DbWriteOperation dbWriteOperation) {
- int cursorCount = 0;
- int totalRowcount = 0;
- // Set to check the uniqueness of tokens across pages.
- Set<String> tokens = new ArraySet<>();
-
- String nextPageToken = null;
- do {
- if (nextPageToken != null) {
- queryArgs.putString(EXTRA_PAGE_TOKEN, nextPageToken);
- }
+ Trace.beginSection(traceSectionName("executePagedSync"));
+ try {
+ int cursorCount = 0;
+ int totalRowcount = 0;
+ // Set to check the uniqueness of tokens across pages.
+ Set<String> tokens = new ArraySet<>();
+
+ String nextPageToken = null;
+ do {
+ if (nextPageToken != null) {
+ queryArgs.putString(EXTRA_PAGE_TOKEN, nextPageToken);
+ }
- try (Cursor cursor = query(uri, queryArgs)) {
- nextPageToken = validateCursor(cursor, expectedMediaCollectionId,
- expectedHonoredArgs, tokens);
+ try (Cursor cursor = query(uri, queryArgs)) {
+ nextPageToken = validateCursor(cursor, expectedMediaCollectionId,
+ expectedHonoredArgs, tokens);
- int writeCount = dbWriteOperation.execute(cursor);
+ int writeCount = dbWriteOperation.execute(cursor);
- totalRowcount += writeCount;
- cursorCount += cursor.getCount();
- }
- } while (nextPageToken != null);
+ totalRowcount += writeCount;
+ cursorCount += cursor.getCount();
+ }
+ } while (nextPageToken != null);
- dbWriteOperation.setSuccess();
- Log.i(TAG, "Paged sync successful. QueryArgs: " + queryArgs + ". Result count: "
- + totalRowcount + ". Cursor count: " + cursorCount);
+ dbWriteOperation.setSuccess();
+ Log.i(TAG, "Paged sync successful. QueryArgs: " + queryArgs + ". Result count: "
+ + totalRowcount + ". Cursor count: " + cursorCount);
+ } finally {
+ Trace.endSection();
+ }
}
/**
@@ -797,6 +843,15 @@ public class PickerSyncController {
/* defaultValue */ false);
}
+ private static String traceSectionName(@NonNull String method) {
+ return "PSC." + method;
+ }
+
+ private static String traceSectionName(@NonNull String method, boolean isLocal) {
+ return traceSectionName(method)
+ + "[" + (isLocal ? "local" : "cloud") + ']';
+ }
+
private static String validateCursor(Cursor cursor, String expectedMediaCollectionId,
List<String> expectedHonoredArgs, Set<String> usedPageTokens) {
final Bundle bundle = cursor.getExtras();
@@ -857,7 +912,7 @@ public class PickerSyncController {
}
String getMediaCollectionId() {
- return latestMediaCollectionInfo.getString(MediaCollectionInfo.MEDIA_COLLECTION_ID);
+ return latestMediaCollectionInfo.getString(MEDIA_COLLECTION_ID);
}
static SyncRequestParams forNone() {
diff --git a/src/com/android/providers/media/photopicker/data/PickerDbFacade.java b/src/com/android/providers/media/photopicker/data/PickerDbFacade.java
index 7549f21ab..b41af8ab6 100644
--- a/src/com/android/providers/media/photopicker/data/PickerDbFacade.java
+++ b/src/com/android/providers/media/photopicker/data/PickerDbFacade.java
@@ -37,6 +37,7 @@ import android.database.sqlite.SQLiteConstraintException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
+import android.os.Trace;
import android.provider.CloudMediaProviderContract;
import android.provider.MediaStore;
import android.text.TextUtils;
@@ -284,7 +285,14 @@ public class PickerDbFacade {
if (!mDatabase.inTransaction()) {
throw new IllegalStateException("No ongoing DB transaction.");
}
- return executeInternal(cursor);
+ final String traceSectionName = getClass().getSimpleName()
+ + ".execute[" + (mIsLocal ? "local" : "cloud") + ']';
+ Trace.beginSection(traceSectionName);
+ try {
+ return executeInternal(cursor);
+ } finally {
+ Trace.endSection();
+ }
}
public void setSuccess() {
diff --git a/src/com/android/providers/media/scan/ModernMediaScanner.java b/src/com/android/providers/media/scan/ModernMediaScanner.java
index 5afe15e1f..177013658 100644
--- a/src/com/android/providers/media/scan/ModernMediaScanner.java
+++ b/src/com/android/providers/media/scan/ModernMediaScanner.java
@@ -349,7 +349,7 @@ public class ModernMediaScanner implements MediaScanner {
public Scan(File root, int reason, @Nullable String ownerPackage)
throws FileNotFoundException {
- Trace.beginSection("ctor");
+ Trace.beginSection("Scanner.ctor");
mClient = mContext.getContentResolver()
.acquireContentProviderClient(MediaStore.AUTHORITY);
@@ -417,7 +417,7 @@ public class ModernMediaScanner implements MediaScanner {
shouldScanPathAndIsPathHidden(mSingleFile ? mRoot.getParentFile() : mRoot);
if (isDirScannableAndHidden.first) {
// This directory is scannable.
- Trace.beginSection("walkFileTree");
+ Trace.beginSection("Scanner.walkFileTree");
if (isDirScannableAndHidden.second) {
// This directory is hidden
@@ -491,7 +491,7 @@ public class ModernMediaScanner implements MediaScanner {
// The query phase is split from the delete phase so that our query
// remains stable if we need to paginate across multiple windows.
mSignal.throwIfCanceled();
- Trace.beginSection("reconcile");
+ Trace.beginSection("Scanner.reconcile");
// Ignore abstract playlists which don't have files on disk
final String formatClause = "ifnull(" + FileColumns.FORMAT + ","
@@ -546,7 +546,7 @@ public class ModernMediaScanner implements MediaScanner {
// Third, clean all the unknown database entries found above
mSignal.throwIfCanceled();
- Trace.beginSection("clean");
+ Trace.beginSection("Scanner.clean");
try {
for (int i = 0; i < mUnknownIds.size(); i++) {
final long id = mUnknownIds.get(i);
@@ -595,7 +595,7 @@ public class ModernMediaScanner implements MediaScanner {
* and confuse each other.
*/
private void acquireDirectoryLock(@NonNull Path dir) {
- Trace.beginSection("acquireDirectoryLock");
+ Trace.beginSection("Scanner.acquireDirectoryLock");
DirectoryLock lock;
synchronized (mDirectoryLocks) {
lock = mDirectoryLocks.get(dir);
@@ -616,7 +616,7 @@ public class ModernMediaScanner implements MediaScanner {
* structures if no other threads are waiting.
*/
private void releaseDirectoryLock(@NonNull Path dir) {
- Trace.beginSection("releaseDirectoryLock");
+ Trace.beginSection("Scanner.releaseDirectoryLock");
DirectoryLock lock;
synchronized (mDirectoryLocks) {
lock = mDirectoryLocks.get(dir);
@@ -718,7 +718,7 @@ public class ModernMediaScanner implements MediaScanner {
int actualMediaType = mediaTypeFromMimeType(
realFile, actualMimeType, FileColumns.MEDIA_TYPE_NONE);
- Trace.beginSection("checkChanged");
+ Trace.beginSection("Scanner.checkChanged");
final Bundle queryArgs = new Bundle();
queryArgs.putString(ContentResolver.QUERY_ARG_SQL_SELECTION,
@@ -789,7 +789,7 @@ public class ModernMediaScanner implements MediaScanner {
}
final ContentProviderOperation.Builder op;
- Trace.beginSection("scanItem");
+ Trace.beginSection("Scanner.scanItem");
try {
op = scanItem(existingId, realFile, attrs, actualMimeType, actualMediaType,
mVolumeName);
@@ -910,7 +910,7 @@ public class ModernMediaScanner implements MediaScanner {
// Bail early when nothing pending
if (mPending.isEmpty()) return;
- Trace.beginSection("applyPending");
+ Trace.beginSection("Scanner.applyPending");
try {
ContentProviderResult[] results = mResolver.applyBatch(AUTHORITY, mPending);
for (int index = 0; index < results.length; index++) {
@@ -1626,7 +1626,7 @@ public class ModernMediaScanner implements MediaScanner {
* path should be considered hidden.
*/
static Pair<Boolean, Boolean> shouldScanPathAndIsPathHidden(@NonNull File dir) {
- Trace.beginSection("shouldScanPathAndIsPathHiodden");
+ Trace.beginSection("Scanner.shouldScanPathAndIsPathHidden");
try {
boolean isPathHidden = false;
while (dir != null) {
diff --git a/src/com/android/providers/media/util/DatabaseUtils.java b/src/com/android/providers/media/util/DatabaseUtils.java
index cec6f27f1..e83d05c98 100644
--- a/src/com/android/providers/media/util/DatabaseUtils.java
+++ b/src/com/android/providers/media/util/DatabaseUtils.java
@@ -48,7 +48,6 @@ import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
import java.util.Locale;
import java.util.function.Consumer;
@@ -451,7 +450,7 @@ public class DatabaseUtils {
public static long executeInsert(@NonNull SQLiteDatabase db, @NonNull String sql,
@Nullable Object[] bindArgs) throws SQLException {
- Trace.beginSection("executeInsert");
+ Trace.beginSection("DbUtils.executeInsert");
try (SQLiteStatement st = db.compileStatement(sql)) {
bindArgs(st, bindArgs);
return st.executeInsert();
@@ -462,7 +461,7 @@ public class DatabaseUtils {
public static int executeUpdateDelete(@NonNull SQLiteDatabase db, @NonNull String sql,
@Nullable Object[] bindArgs) throws SQLException {
- Trace.beginSection("executeUpdateDelete");
+ Trace.beginSection("DbUtils.executeUpdateDelete");
try (SQLiteStatement st = db.compileStatement(sql)) {
bindArgs(st, bindArgs);
return st.executeUpdateDelete();
diff --git a/src/com/android/providers/media/util/SpecialFormatDetector.java b/src/com/android/providers/media/util/SpecialFormatDetector.java
index d8d65d94e..a8569d746 100644
--- a/src/com/android/providers/media/util/SpecialFormatDetector.java
+++ b/src/com/android/providers/media/util/SpecialFormatDetector.java
@@ -29,9 +29,9 @@ import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
+import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
-import java.io.File;
import java.io.StringReader;
import java.nio.charset.StandardCharsets;
@@ -143,7 +143,7 @@ public class SpecialFormatDetector {
return false;
}
- Trace.beginSection("motionPhotoDetectionUsingXpp");
+ Trace.beginSection("FormatDetector.motionPhotoDetectionUsingXpp");
try {
return isMotionPhoto(xpp);
} finally {
diff --git a/src/com/android/providers/media/util/XAttrUtils.java b/src/com/android/providers/media/util/XAttrUtils.java
index 236f7ed13..31dbe8ab7 100644
--- a/src/com/android/providers/media/util/XAttrUtils.java
+++ b/src/com/android/providers/media/util/XAttrUtils.java
@@ -62,7 +62,7 @@ public class XAttrUtils {
public static Optional<FileAccessAttributes> getFileAttributesFromXAttr(String path,
String key) {
- Trace.beginSection("getFileAttributesFromXAttr");
+ Trace.beginSection("XAttrUtils.getFileAttributesFromXAttr");
String relativePathWithDisplayName = DATA_MEDIA_XATTR_DIRECTORY_PATH + "/"
+ extractRelativePath(path) + extractDisplayName(path);
try {
diff --git a/trace.sh b/trace.sh
index 410e8f073..57e58cd6a 100755
--- a/trace.sh
+++ b/trace.sh
@@ -1 +1,3 @@
-./external/chromium-trace/systrace.py -b 128768 -a com.google.android.providers.media.module,com.android.providers.media.module binder_driver
+$ANDROID_BUILD_TOP/external/perfetto/tools/record_android_trace \
+ -c $ANDROID_BUILD_TOP/packages/providers/MediaProvider/perfetto_config.pbtx \
+ -o /tmp/perfetto-traces/$(date +"%d-%m-%Y_%H-%M-%S").perfetto-trace