summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author josephpv <josephpv@google.com> 2025-03-06 11:45:37 +0000
committer Joseph Vincent <josephpv@google.com> 2025-03-14 01:46:03 -0700
commit29cf9957e7f2fa1c5daad8d8b1a10ac80545836f (patch)
tree53c0912e6e39b7a4295c2b3cb9ec4716d72a6c91
parenta76927b02bf259ea557d4cdf1cd3967f29f72851 (diff)
Add event logging for Transcoding usage
This change logs a new boolean to PhotopickerApiInfoEvent to indicate the usage of transcoding by the app and the app media capabilities. Logs the trascoding video info and transcoding status. Bug: 384475921 Test: atest DispatchersTest Flag: EXEMPT Bug fix Change-Id: Ic99c95cd9b275282dfa21d3b5b02afa504676fed
-rw-r--r--pdf/framework/Android.bp1
-rw-r--r--photopicker/src/com/android/photopicker/MainActivity.kt7
-rw-r--r--photopicker/src/com/android/photopicker/core/events/Dispatchers.kt60
-rw-r--r--photopicker/src/com/android/photopicker/core/events/Event.kt79
-rw-r--r--photopicker/src/com/android/photopicker/core/events/PhotopickerEventLogger.kt19
-rw-r--r--photopicker/src/com/android/photopicker/core/features/FeatureManager.kt2
-rw-r--r--photopicker/src/com/android/photopicker/features/preparemedia/MediaPreparerViewModel.kt47
-rw-r--r--photopicker/src/com/android/photopicker/features/preparemedia/Transcoder.kt11
-rw-r--r--photopicker/src/com/android/photopicker/features/preparemedia/TranscoderImpl.kt33
-rw-r--r--photopicker/tests/src/com/android/photopicker/core/configuration/TestPhotopickerConfiguration.kt7
-rw-r--r--photopicker/tests/src/com/android/photopicker/core/events/DispatchersTest.kt45
11 files changed, 309 insertions, 2 deletions
diff --git a/pdf/framework/Android.bp b/pdf/framework/Android.bp
index d67506690..d2d9459e9 100644
--- a/pdf/framework/Android.bp
+++ b/pdf/framework/Android.bp
@@ -136,6 +136,7 @@ java_library {
libs: [
// To add StatsLog as a dependency of the generated file.
"framework-statsd.stubs.module_lib",
+ "androidx.annotation_annotation",
],
apex_available: [
"com.android.mediaprovider",
diff --git a/photopicker/src/com/android/photopicker/MainActivity.kt b/photopicker/src/com/android/photopicker/MainActivity.kt
index 22bf6bd16..8b148df60 100644
--- a/photopicker/src/com/android/photopicker/MainActivity.kt
+++ b/photopicker/src/com/android/photopicker/MainActivity.kt
@@ -56,6 +56,7 @@ import com.android.photopicker.core.events.Telemetry
import com.android.photopicker.core.events.dispatchReportPhotopickerApiInfoEvent
import com.android.photopicker.core.events.dispatchReportPhotopickerMediaItemStatusEvent
import com.android.photopicker.core.events.dispatchReportPhotopickerSessionInfoEvent
+import com.android.photopicker.core.events.dispatchReportPickerAppMediaCapabilities
import com.android.photopicker.core.features.FeatureManager
import com.android.photopicker.core.features.LocalFeatureManager
import com.android.photopicker.core.selection.GrantsAwareSelectionImpl
@@ -289,6 +290,12 @@ class MainActivity : Hilt_MainActivity() {
pickerIntentAction = intentAction,
lazyFeatureManager = featureManager,
)
+
+ dispatchReportPickerAppMediaCapabilities(
+ coroutineScope = lifecycleScope,
+ lazyEvents = events,
+ photopickerConfiguration = configurationManager.configuration.value,
+ )
}
/**
diff --git a/photopicker/src/com/android/photopicker/core/events/Dispatchers.kt b/photopicker/src/com/android/photopicker/core/events/Dispatchers.kt
index 1984a4335..e27cb75fd 100644
--- a/photopicker/src/com/android/photopicker/core/events/Dispatchers.kt
+++ b/photopicker/src/com/android/photopicker/core/events/Dispatchers.kt
@@ -16,6 +16,8 @@
package com.android.photopicker.core.events
+import android.media.ApplicationMediaCapabilities
+import android.media.MediaFeature
import android.provider.MediaStore
import com.android.photopicker.core.configuration.PhotopickerConfiguration
import com.android.photopicker.core.configuration.PhotopickerRuntimeEnv
@@ -80,6 +82,8 @@ fun dispatchReportPhotopickerApiInfoEvent(
val isCloudSearchEnabled = lazyFeatureManager.get().isFeatureEnabled(SearchFeature::class.java)
// TODO(b/376822503): Update when search is added
val isLocalSearchEnabled = false
+ val isTranscodingRequested: Boolean =
+ photopickerConfiguration.callingPackageMediaCapabilities != null
coroutineScope.launch {
lazyEvents
.get()
@@ -98,11 +102,67 @@ fun dispatchReportPhotopickerApiInfoEvent(
isDefaultTabSet = isDefaultTabSet,
isCloudSearchEnabled = isCloudSearchEnabled,
isLocalSearchEnabled = isLocalSearchEnabled,
+ isTranscodingRequested = isTranscodingRequested,
)
)
}
}
+/** Dispatches an event to log App transcoding media capabilities if advertised by the app */
+fun dispatchReportPickerAppMediaCapabilities(
+ coroutineScope: CoroutineScope,
+ lazyEvents: Lazy<Events>,
+ photopickerConfiguration: PhotopickerConfiguration,
+) {
+ val dispatcherToken = FeatureToken.CORE.token
+ val sessionId = photopickerConfiguration.sessionId
+ val appMediaCapabilities: ApplicationMediaCapabilities? =
+ photopickerConfiguration.callingPackageMediaCapabilities
+ if (appMediaCapabilities != null) {
+ with(appMediaCapabilities) {
+ val supportedHdrTypes: IntArray = getEnumsForTypes(true, getSupportedHdrTypes())
+ val unsupportedHdrTypes: IntArray = getEnumsForTypes(false, getUnsupportedHdrTypes())
+ coroutineScope.launch {
+ lazyEvents
+ .get()
+ .dispatch(
+ Event.ReportPickerAppMediaCapabilities(
+ dispatcherToken = dispatcherToken,
+ sessionId = sessionId,
+ supportedHdrTypes = supportedHdrTypes,
+ unsupportedHdrTypes = unsupportedHdrTypes,
+ )
+ )
+ }
+ }
+ }
+}
+
+private fun getEnumsForTypes(supported: Boolean, hdrTypesList: List<String>): IntArray {
+ var array: MutableList<Int> = mutableListOf()
+ for (type in hdrTypesList) {
+ when (type) {
+ MediaFeature.HdrType.DOLBY_VISION -> {
+ if (supported) array.add(Telemetry.HdrTypes.DOLBY_SUPPORTED.type)
+ else array.add(Telemetry.HdrTypes.DOLBY_UNSUPPORTED.type)
+ }
+ MediaFeature.HdrType.HDR10 -> {
+ if (supported) array.add(Telemetry.HdrTypes.HDR10_SUPPORTED.type)
+ else array.add(Telemetry.HdrTypes.HDR10_UNSUPPORTED.type)
+ }
+ MediaFeature.HdrType.HDR10_PLUS -> {
+ if (supported) array.add(Telemetry.HdrTypes.HDR10PLUS_SUPPORTED.type)
+ else array.add(Telemetry.HdrTypes.HDR10PLUS_UNSUPPORTED.type)
+ }
+ MediaFeature.HdrType.HLG -> {
+ if (supported) array.add(Telemetry.HdrTypes.HLG_SUPPORTED.type)
+ else array.add(Telemetry.HdrTypes.HLG_UNSUPPORTED.type)
+ }
+ }
+ }
+ return array.toIntArray()
+}
+
/** Dispatches an event to log all the final state details of the picker */
fun dispatchReportPhotopickerSessionInfoEvent(
coroutineScope: CoroutineScope,
diff --git a/photopicker/src/com/android/photopicker/core/events/Event.kt b/photopicker/src/com/android/photopicker/core/events/Event.kt
index 00d7b0ca5..c6b674c90 100644
--- a/photopicker/src/com/android/photopicker/core/events/Event.kt
+++ b/photopicker/src/com/android/photopicker/core/events/Event.kt
@@ -96,6 +96,7 @@ interface Event {
val isDefaultTabSet: Boolean,
val isCloudSearchEnabled: Boolean,
val isLocalSearchEnabled: Boolean,
+ val isTranscodingRequested: Boolean,
) : Event
/**
@@ -225,6 +226,24 @@ interface Event {
val surfacePackageDeliveryStartTime: Int,
val surfacePackageDeliveryEndTime: Int,
) : Event
+
+ /** Logs media capabilities of the App requesting transcoding */
+ data class ReportPickerAppMediaCapabilities(
+ override val dispatcherToken: String,
+ val sessionId: Int,
+ val supportedHdrTypes: IntArray,
+ val unsupportedHdrTypes: IntArray,
+ ) : Event
+
+ /** Logs information about the transcoding video */
+ data class ReportTranscodingVideoDetails(
+ override val dispatcherToken: String,
+ val sessionId: Int,
+ val duration: Int,
+ val colorTransfer: Int,
+ val colorStandard: Int,
+ val mimeType: Int,
+ ) : Event
}
/**
@@ -383,6 +402,57 @@ interface Telemetry {
}
/*
+ Different supported and unsupported HDR types
+ */
+ enum class HdrTypes(val type: Int) {
+ HDR10_SUPPORTED(
+ MediaProviderStatsLog
+ .PHOTOPICKER_APP_MEDIA_CAPABILITIES_REPORTED__SUPPORTED_HDR_TYPES__TYPE_HDR10
+ ),
+ HDR10PLUS_SUPPORTED(
+ MediaProviderStatsLog
+ .PHOTOPICKER_APP_MEDIA_CAPABILITIES_REPORTED__SUPPORTED_HDR_TYPES__TYPE_HDR10_PLUS
+ ),
+ HLG_SUPPORTED(
+ MediaProviderStatsLog
+ .PHOTOPICKER_APP_MEDIA_CAPABILITIES_REPORTED__SUPPORTED_HDR_TYPES__TYPE_HLG
+ ),
+ DOLBY_SUPPORTED(
+ MediaProviderStatsLog
+ .PHOTOPICKER_APP_MEDIA_CAPABILITIES_REPORTED__SUPPORTED_HDR_TYPES__TYPE_DOLBY_VISION
+ ),
+ HDR10_UNSUPPORTED(
+ MediaProviderStatsLog
+ .PHOTOPICKER_APP_MEDIA_CAPABILITIES_REPORTED__UNSUPPORTED_HDR_TYPES__TYPE_HDR10
+ ),
+ HDR10PLUS_UNSUPPORTED(
+ MediaProviderStatsLog
+ .PHOTOPICKER_APP_MEDIA_CAPABILITIES_REPORTED__UNSUPPORTED_HDR_TYPES__TYPE_HDR10_PLUS
+ ),
+ HLG_UNSUPPORTED(
+ MediaProviderStatsLog
+ .PHOTOPICKER_APP_MEDIA_CAPABILITIES_REPORTED__UNSUPPORTED_HDR_TYPES__TYPE_HLG
+ ),
+ DOLBY_UNSUPPORTED(
+ MediaProviderStatsLog
+ .PHOTOPICKER_APP_MEDIA_CAPABILITIES_REPORTED__UNSUPPORTED_HDR_TYPES__TYPE_DOLBY_VISION
+ ),
+ }
+
+ /*
+ Different Video mime types
+ */
+ enum class VideoMimeType(val type: Int) {
+ DOLBY(
+ MediaProviderStatsLog
+ .PHOTOPICKER_VIDEO_TRANSCODING_DETAILS_LOGGED__MIME_TYPE__MIME_DOLBY
+ ),
+ HEVC(
+ MediaProviderStatsLog.PHOTOPICKER_VIDEO_TRANSCODING_DETAILS_LOGGED__MIME_TYPE__MIME_HEVC
+ ),
+ }
+
+ /*
Different picker tabs
*/
enum class SelectedTab(val tab: Int) {
@@ -556,6 +626,15 @@ interface Telemetry {
MediaProviderStatsLog.PHOTOPICKER_UIEVENT_LOGGED__UI_EVENT__UI_LOADED_EMPTY_STATE
),
UNSET_UI_EVENT(MediaProviderStatsLog.PHOTOPICKER_UIEVENT_LOGGED__UI_EVENT__UNSET_UI_EVENT),
+ PICKER_TRANSCODING_START(
+ MediaProviderStatsLog.PHOTOPICKER_UIEVENT_LOGGED__UI_EVENT__PICKER_TRANSCODING_STARTED
+ ),
+ PICKER_TRANSCODING_SUCCESS(
+ MediaProviderStatsLog.PHOTOPICKER_UIEVENT_LOGGED__UI_EVENT__PICKER_TRANSCODING_FINISHED
+ ),
+ PICKER_TRANSCODING_FAILED(
+ MediaProviderStatsLog.PHOTOPICKER_UIEVENT_LOGGED__UI_EVENT__PICKER_TRANSCODING_FAILED
+ ),
}
/*
diff --git a/photopicker/src/com/android/photopicker/core/events/PhotopickerEventLogger.kt b/photopicker/src/com/android/photopicker/core/events/PhotopickerEventLogger.kt
index c6bc6445f..5f3787d76 100644
--- a/photopicker/src/com/android/photopicker/core/events/PhotopickerEventLogger.kt
+++ b/photopicker/src/com/android/photopicker/core/events/PhotopickerEventLogger.kt
@@ -100,6 +100,7 @@ class PhotopickerEventLogger(val dataService: Lazy<DataService>) {
/* is_search_enabled */ false,
event.isCloudSearchEnabled,
event.isLocalSearchEnabled,
+ event.isTranscodingRequested,
)
}
is Event.LogPhotopickerUIEvent -> {
@@ -256,6 +257,24 @@ class PhotopickerEventLogger(val dataService: Lazy<DataService>) {
event.surfacePackageDeliveryEndTime,
)
}
+ is Event.ReportPickerAppMediaCapabilities -> {
+ MediaProviderStatsLog.write(
+ MediaProviderStatsLog.PHOTOPICKER_APP_MEDIA_CAPABILITIES_REPORTED,
+ event.sessionId,
+ event.supportedHdrTypes,
+ event.unsupportedHdrTypes,
+ )
+ }
+ is Event.ReportTranscodingVideoDetails -> {
+ MediaProviderStatsLog.write(
+ MediaProviderStatsLog.PHOTOPICKER_VIDEO_TRANSCODING_DETAILS_LOGGED,
+ event.sessionId,
+ event.duration,
+ event.colorStandard,
+ event.colorTransfer,
+ event.mimeType,
+ )
+ }
}
}
}
diff --git a/photopicker/src/com/android/photopicker/core/features/FeatureManager.kt b/photopicker/src/com/android/photopicker/core/features/FeatureManager.kt
index 0fd821eb6..c1ff94c45 100644
--- a/photopicker/src/com/android/photopicker/core/features/FeatureManager.kt
+++ b/photopicker/src/com/android/photopicker/core/features/FeatureManager.kt
@@ -121,6 +121,8 @@ class FeatureManager(
Event.ReportPhotopickerSearchInfo::class.java,
Event.ReportSearchDataExtractionDetails::class.java,
Event.ReportEmbeddedPhotopickerInfo::class.java,
+ Event.ReportPickerAppMediaCapabilities::class.java,
+ Event.ReportTranscodingVideoDetails::class.java,
)
}
diff --git a/photopicker/src/com/android/photopicker/features/preparemedia/MediaPreparerViewModel.kt b/photopicker/src/com/android/photopicker/features/preparemedia/MediaPreparerViewModel.kt
index 41753b265..df626b1a9 100644
--- a/photopicker/src/com/android/photopicker/features/preparemedia/MediaPreparerViewModel.kt
+++ b/photopicker/src/com/android/photopicker/features/preparemedia/MediaPreparerViewModel.kt
@@ -474,6 +474,31 @@ constructor(
// Trigger transcoding.
val transcodeStatus =
if (transcoder.isTranscodeRequired(context, mediaCapabilities, item)) {
+ val transcodingVideoInfo: Transcoder.VideoInfo? =
+ transcoder.getTranscodingVideoInfo()
+ scope.launch {
+ val configuration = configurationManager.configuration.value
+ if (transcodingVideoInfo != null) {
+ events.dispatch(
+ Event.ReportTranscodingVideoDetails(
+ dispatcherToken = FeatureToken.CORE.token,
+ sessionId = configuration.sessionId,
+ duration = transcodingVideoInfo.duration,
+ colorTransfer = transcodingVideoInfo.colorTransfer,
+ colorStandard = transcodingVideoInfo.colorStandard,
+ mimeType = transcodingVideoInfo.mimeType,
+ )
+ )
+ }
+ events.dispatch(
+ Event.LogPhotopickerUIEvent(
+ FeatureToken.CORE.token,
+ configuration.sessionId,
+ configuration.callingPackageUid ?: -1,
+ Telemetry.UiEvent.PICKER_TRANSCODING_START,
+ )
+ )
+ }
val uri = item.mediaUri
val resultBundle =
contentResolver.call(
@@ -485,9 +510,31 @@ constructor(
if (resultBundle?.getBoolean(PICKER_TRANSCODE_RESULT, false) == true) {
Log.v(PrepareMediaFeature.TAG, "Transcode successful: $item")
+ scope.launch {
+ val configuration = configurationManager.configuration.value
+ events.dispatch(
+ Event.LogPhotopickerUIEvent(
+ FeatureToken.CORE.token,
+ configuration.sessionId,
+ configuration.callingPackageUid ?: -1,
+ Telemetry.UiEvent.PICKER_TRANSCODING_SUCCESS,
+ )
+ )
+ }
TranscodeStatus.SUCCEED
} else {
Log.w(PrepareMediaFeature.TAG, "Not able to transcode: $item")
+ scope.launch {
+ val configuration = configurationManager.configuration.value
+ events.dispatch(
+ Event.LogPhotopickerUIEvent(
+ FeatureToken.CORE.token,
+ configuration.sessionId,
+ configuration.callingPackageUid ?: -1,
+ Telemetry.UiEvent.PICKER_TRANSCODING_FAILED,
+ )
+ )
+ }
TranscodeStatus.NOT_APPLIED
}
} else {
diff --git a/photopicker/src/com/android/photopicker/features/preparemedia/Transcoder.kt b/photopicker/src/com/android/photopicker/features/preparemedia/Transcoder.kt
index f2f82e89e..5b1bb38fd 100644
--- a/photopicker/src/com/android/photopicker/features/preparemedia/Transcoder.kt
+++ b/photopicker/src/com/android/photopicker/features/preparemedia/Transcoder.kt
@@ -26,6 +26,14 @@ import com.android.photopicker.data.model.Media
/** Provides methods to help video transcode. */
interface Transcoder {
+ /** Data class to hold details of the transcoding video. */
+ data class VideoInfo(
+ val duration: Int,
+ val colorStandard: Int,
+ val colorTransfer: Int,
+ val mimeType: Int,
+ )
+
/**
* Checks if a transcode is required for the given video.
*
@@ -39,6 +47,9 @@ interface Transcoder {
video: Media.Video,
): Boolean
+ /** Returns details of the video that needs transcoding */
+ fun getTranscodingVideoInfo(): VideoInfo?
+
companion object {
/**
diff --git a/photopicker/src/com/android/photopicker/features/preparemedia/TranscoderImpl.kt b/photopicker/src/com/android/photopicker/features/preparemedia/TranscoderImpl.kt
index 547440037..bf48ed34f 100644
--- a/photopicker/src/com/android/photopicker/features/preparemedia/TranscoderImpl.kt
+++ b/photopicker/src/com/android/photopicker/features/preparemedia/TranscoderImpl.kt
@@ -31,11 +31,14 @@ import androidx.annotation.VisibleForTesting
import androidx.media3.common.util.MediaFormatUtil.createFormatFromMediaFormat
import androidx.media3.common.util.MediaFormatUtil.isVideoFormat
import androidx.media3.exoplayer.MediaExtractorCompat
+import com.android.photopicker.core.events.Telemetry
import com.android.photopicker.data.model.Media
/** A class that help video transcode. */
class TranscoderImpl : Transcoder {
+ private var needsTranscodingVideoInfo: Transcoder.VideoInfo? = null
+
override fun isTranscodeRequired(
context: Context,
mediaCapabilities: ApplicationMediaCapabilities?,
@@ -53,7 +56,7 @@ class TranscoderImpl : Transcoder {
// Check if any video tracks need to be transcoded.
val videoTrackMediaFormats = getVideoTrackMediaFormats(context, video)
for (mediaFormat in videoTrackMediaFormats) {
- if (isTranscodeRequired(mediaFormat, mediaCapabilities)) {
+ if (isTranscodeRequired(mediaFormat, mediaCapabilities, video.duration)) {
return true
}
}
@@ -98,6 +101,7 @@ class TranscoderImpl : Transcoder {
fun isTranscodeRequired(
mediaFormat: MediaFormat,
mediaCapabilities: ApplicationMediaCapabilities,
+ duration: Int = 0,
): Boolean {
val format = createFormatFromMediaFormat(mediaFormat)
val mimeType = format.sampleMimeType
@@ -111,6 +115,13 @@ class TranscoderImpl : Transcoder {
// what the caller intended.
if (isHlg10(colorStandard, colorTransfer) && !isHdrTypeSupported(HdrType.HLG)) {
+ needsTranscodingVideoInfo =
+ Transcoder.VideoInfo(
+ duration,
+ colorStandard ?: 0,
+ colorTransfer ?: 0,
+ Telemetry.VideoMimeType.HEVC.type,
+ )
return true
}
@@ -119,6 +130,13 @@ class TranscoderImpl : Transcoder {
(!isHdrTypeSupported(HdrType.HDR10) ||
!isHdrTypeSupported(HdrType.HDR10_PLUS))
) {
+ needsTranscodingVideoInfo =
+ Transcoder.VideoInfo(
+ duration,
+ colorStandard ?: 0,
+ colorTransfer ?: 0,
+ Telemetry.VideoMimeType.HEVC.type,
+ )
return true
}
}
@@ -127,13 +145,24 @@ class TranscoderImpl : Transcoder {
isHdrDolbyVision(mimeType, colorStandard, colorTransfer) &&
!isHdrTypeSupported(HdrType.DOLBY_VISION)
) {
+ needsTranscodingVideoInfo =
+ Transcoder.VideoInfo(
+ duration,
+ colorStandard ?: 0,
+ colorTransfer ?: 0,
+ Telemetry.VideoMimeType.DOLBY.type,
+ )
return true
}
}
-
return false
}
+ /** Returns details of the video that needs transcoding */
+ override fun getTranscodingVideoInfo(): Transcoder.VideoInfo? {
+ return needsTranscodingVideoInfo
+ }
+
companion object {
private const val TAG = "Transcoder"
@VisibleForTesting const val DURATION_LIMIT_MS = 60_000L // 1 min
diff --git a/photopicker/tests/src/com/android/photopicker/core/configuration/TestPhotopickerConfiguration.kt b/photopicker/tests/src/com/android/photopicker/core/configuration/TestPhotopickerConfiguration.kt
index e444adabb..4382acead 100644
--- a/photopicker/tests/src/com/android/photopicker/core/configuration/TestPhotopickerConfiguration.kt
+++ b/photopicker/tests/src/com/android/photopicker/core/configuration/TestPhotopickerConfiguration.kt
@@ -17,6 +17,7 @@
package com.android.photopicker.core.configuration
import android.content.Intent
+import android.media.ApplicationMediaCapabilities
import com.android.photopicker.core.events.generatePickerSessionId
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.SharingStarted
@@ -69,6 +70,7 @@ class TestPhotopickerConfiguration {
private var sessionId: Int = generatePickerSessionId()
private var flags: PhotopickerFlags = PhotopickerFlags()
private var mimeTypes: ArrayList<String> = arrayListOf("image/*", "video/*")
+ private var appMediaCapabilities: ApplicationMediaCapabilities? = null
fun action(value: String) = apply { this.action = value }
@@ -92,6 +94,10 @@ class TestPhotopickerConfiguration {
fun mimeTypes(value: ArrayList<String>) = apply { this.mimeTypes = value }
+ fun appMediaCapabilities(value: ApplicationMediaCapabilities) = apply {
+ this.appMediaCapabilities = value
+ }
+
fun build(): PhotopickerConfiguration {
return PhotopickerConfiguration(
action = action,
@@ -105,6 +111,7 @@ class TestPhotopickerConfiguration {
sessionId = sessionId,
flags = flags,
mimeTypes = mimeTypes,
+ callingPackageMediaCapabilities = appMediaCapabilities,
)
}
}
diff --git a/photopicker/tests/src/com/android/photopicker/core/events/DispatchersTest.kt b/photopicker/tests/src/com/android/photopicker/core/events/DispatchersTest.kt
index 90afd5811..396a6bee0 100644
--- a/photopicker/tests/src/com/android/photopicker/core/events/DispatchersTest.kt
+++ b/photopicker/tests/src/com/android/photopicker/core/events/DispatchersTest.kt
@@ -20,6 +20,8 @@ import android.content.ContentResolver
import android.content.Context
import android.content.pm.PackageManager
import android.content.pm.UserProperties
+import android.media.ApplicationMediaCapabilities
+import android.media.MediaFeature.HdrType
import android.net.Uri
import android.os.Parcel
import android.os.UserHandle
@@ -39,6 +41,7 @@ import com.android.photopicker.core.events.dispatchPhotopickerExpansionStateChan
import com.android.photopicker.core.events.dispatchReportPhotopickerApiInfoEvent
import com.android.photopicker.core.events.dispatchReportPhotopickerMediaItemStatusEvent
import com.android.photopicker.core.events.dispatchReportPhotopickerSessionInfoEvent
+import com.android.photopicker.core.events.dispatchReportPickerAppMediaCapabilities
import com.android.photopicker.core.events.generatePickerSessionId
import com.android.photopicker.core.features.FeatureManager
import com.android.photopicker.core.features.FeatureToken
@@ -390,6 +393,7 @@ class DispatchersTest {
isDefaultTabSet = false,
isCloudSearchEnabled = cloudSearch,
isLocalSearchEnabled = false,
+ isTranscodingRequested = false,
)
// Action
@@ -441,6 +445,7 @@ class DispatchersTest {
isDefaultTabSet = false,
isCloudSearchEnabled = cloudSearch,
isLocalSearchEnabled = false,
+ isTranscodingRequested = false,
)
// Action
@@ -492,6 +497,7 @@ class DispatchersTest {
isDefaultTabSet = false,
isCloudSearchEnabled = cloudSearch,
isLocalSearchEnabled = false,
+ isTranscodingRequested = false,
)
// Action
@@ -543,6 +549,7 @@ class DispatchersTest {
isDefaultTabSet = false,
isCloudSearchEnabled = cloudSearch,
isLocalSearchEnabled = false,
+ isTranscodingRequested = false,
)
// Action
@@ -559,4 +566,42 @@ class DispatchersTest {
assertThat(eventsDispatched).contains(expectedEvent)
assertThat(expectedEvent.mediaFilter).isEqualTo(telemetryMimeTypeMapping)
}
+
+ @Test
+ fun testDispatchReportPickerAppMediaCapabilities() = runTest {
+ // Setup
+ setup(testScope = this)
+
+ val capabilities =
+ ApplicationMediaCapabilities.Builder().addUnsupportedHdrType(HdrType.HDR10).build()
+
+ val photopickerConfiguration =
+ TestPhotopickerConfiguration.build {
+ action(value = "")
+ sessionId(value = sessionId)
+ callingPackageUid(value = packageUid)
+ runtimeEnv(value = PhotopickerRuntimeEnv.EMBEDDED)
+ appMediaCapabilities(capabilities)
+ }
+
+ val expectedEvent =
+ Event.ReportPickerAppMediaCapabilities(
+ dispatcherToken = FeatureToken.CORE.token,
+ sessionId = sessionId,
+ supportedHdrTypes = intArrayOf(),
+ unsupportedHdrTypes = intArrayOf(Telemetry.HdrTypes.HDR10_UNSUPPORTED.type),
+ )
+
+ // Action
+ dispatchReportPickerAppMediaCapabilities(
+ coroutineScope = backgroundScope,
+ lazyEvents = lazyEvents,
+ photopickerConfiguration = photopickerConfiguration,
+ )
+ advanceTimeBy(delayTimeMillis = 50)
+
+ // Assert
+ assertThat(eventsDispatched.size).isEqualTo(1)
+ assertThat(eventsDispatched.get(0).toString()).isEqualTo(expectedEvent.toString())
+ }
}