Skip to content

Enable Google Photos in the device media picker#23102

Open
dcalhoun wants to merge 11 commits into
trunkfrom
feat/photo-picker-select
Open

Enable Google Photos in the device media picker#23102
dcalhoun wants to merge 11 commits into
trunkfrom
feat/photo-picker-select

Conversation

@dcalhoun

@dcalhoun dcalhoun commented Jul 14, 2026

Copy link
Copy Markdown
Member

Description

Fix CMM-2161. Fix CMM-2162.

This adds an enhancement and addresses an existing bug.

Enhancement: Google Photos access from the media grid "Choose from device" picker. In the custom media grid, tapping "Choose from device" previously handed off to the system chooser using whatever media type the flow was configured for. For flows that allow both visual media and other files (e.g. My SiteMedia), the type was ambiguous, so the flow fell back to the file/document browser instead of the system Photo Picker. Now, when the selection is ambiguous, a small menu (anchored to the browse action) lets the user choose "Photos and videos" or "Other files". This improves the selection experience and allows accessing Google Photos albums.

Alternative considered

Replace the "Choose from device" menu item within the existing menu attached to the media grid's + icon button with the new menu items (Photos and videos, Other files). Deferred as a larger change that would remove media grid features (e.g., edit image before uploading) and increase likelihood of regressions.

Bug: Fix empty Google Photos albums. When picking photos/videos, Android 13+ routes the picker to the system Photo Picker, which filters album and cloud contents by an exact match against EXTRA_MIME_TYPES. The app was passing an explicit list of accepted subtypes (image/jpeg, image/heic, …), so Google Photos albums and "From this device" appeared empty because cloud items may not report a matching subtype. Visual contexts now pass a broad type (image/* and/or video/*), matching how other apps behave; audio and document flows keep the explicit accepted-types list.

Historical context found in related PRs:

Testing instructions

Important

These changes do not impact the GutenbergKit editing experience; only the Gutenberg Mobile editor experience.

My Site → Media (originally reported flow):

  1. Go to My Site → Media and tap the + button.
  2. Tap Choose from device, then tap the image icon button in the top-right, then Photos and videos when prompted.
  • Verify the Android Photo Picker opens with Google Photos albums/search.
  1. Open a non-empty Google Photos album or From this device.
  • Verify the album shows its contents (no "No photos yet") and a selected
    photo/video uploads to the site.

Google Photos access (in-grid device picker, editor):

  1. Open the editor and add a File block (a flow that allows mixed media types).
  2. When the custom media grid appears, tap Choose from device, then tap the image icon button in the toolbar.
  • Verify a menu appears (anchored to the action) offering Photos and videos
    and Other files.
  1. Tap Photos and videos.
  • Verify the Android Photo Picker opens with Google Photos albums/search.
  1. Go back and tap Choose from device → Other files.
  • Verify the document/file browser opens for audio and documents.

Empty Google Photos albums fix (other flows):

  1. On a device signed in to Google Photos with a non-empty album, set a
    Featured Image or add an image via an editor image block
  2. When selecting media from the custom media grid, tap the image icon button in the top-right corner, reaching the
    Android Photo Picker.
  3. Navigate to Google Photos Albums or From this device and open an album.
  • Verify the album shows its photos/videos (no "No photos yet").

No behavior change for single-type flows:

  1. Set a Featured Image, Site Icon, or add an image via an editor image block.
  2. When selecting media from the custom media grid, tap the image icon button in the top-right corner.
  • Verify tapping "Choose from device" opens the picker directly with no extra
    menu, and selection/upload works as before.

Regression:

  • Verify audio and document uploads still work.
  • Verify video duration limits and "add media from device" behavior are unchanged (e.g., attempt uploading a video longer than five minutes on a free WP.com site).
Screen_Recording_20260714_104732_Jetpack.Debug.mp4

@wpmobilebot

wpmobilebot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

App Icon📲 You can test the changes from this Pull Request in WordPress Android by scanning the QR code below to install the corresponding build.

App NameWordPress Android
Build TypeDebug
Versionpr23102-aa03e29
Build Number1498
Application IDorg.wordpress.android.prealpha
Commitaa03e29
Installation URL542eaep9g84j8
Automatticians: You can use our internal self-serve MC tool to give yourself access to those builds if needed.

@wpmobilebot

wpmobilebot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

App Icon📲 You can test the changes from this Pull Request in Jetpack Android by scanning the QR code below to install the corresponding build.

App NameJetpack Android
Build TypeDebug
Versionpr23102-aa03e29
Build Number1498
Application IDcom.jetpack.android.prealpha
Commitaa03e29
Installation URL74vv50lhr59jg
Automatticians: You can use our internal self-serve MC tool to give yourself access to those builds if needed.

@codecov

codecov Bot commented Jul 14, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 90.32258% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 37.58%. Comparing base (2d1e81c) to head (aa03e29).
⚠️ Report is 3 commits behind head on trunk.

Files with missing lines Patch % Lines
...ess/android/ui/mediapicker/MediaPickerViewModel.kt 90.90% 0 Missing and 1 partial ⚠️
...ess/android/ui/mediapicker/SystemPickerResolver.kt 94.73% 0 Missing and 1 partial ⚠️
...press/android/ui/posts/editor/EditorPhotoPicker.kt 0.00% 1 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##            trunk   #23102   +/-   ##
=======================================
  Coverage   37.57%   37.58%           
=======================================
  Files        2341     2342    +1     
  Lines      127098   127112   +14     
  Branches    17538    17545    +7     
=======================================
+ Hits        47763    47772    +9     
- Misses      75423    75424    +1     
- Partials     3912     3916    +4     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@dcalhoun dcalhoun force-pushed the feat/photo-picker-select branch from 86037b7 to ef9cca3 Compare July 14, 2026 21:12
dcalhoun and others added 10 commits July 15, 2026 08:12
When the custom media grid's "Choose from device" action allows both
visual media and other files (the editor's add-file flow), tapping it
now shows a menu anchored to the action-bar item: "Photos and videos"
opens the visual picker (which the OS surfaces as the Android Photo
Picker on Android 13+), and "Other files" opens the document/audio
chooser. Flows with a single known type (featured image, site icon,
gravatar, editor photo/video) launch their picker directly, unchanged.

This preserves the custom grid's edit-before-upload capability while
enabling Google Photos browsing via the nested device picker.

- MediaPickerFragment: carry allowedTypes on OpenSystemPicker; add an
  onSystemPickerTypeChosen passthrough.
- MediaPickerViewModel: pass allowedTypes through; re-run the picker
  with a narrowed type set on menu selection; restrict the {AUDIO,
  DOCUMENT} context to audio + document MIME types.
- MediaPickerActivity: show the disambiguation PopupMenu anchored to the
  browse action item when the selection is ambiguous.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
For visual-media contexts, Android 13+ routes ACTION_GET_CONTENT to the
system Photo Picker, which filters album and cloud contents by an exact
match against EXTRA_MIME_TYPES. Passing our explicit list of accepted
subtypes (image/jpeg, image/heic, ...) made Google Photos albums and
"From this device" appear empty ("No photos yet"), because cloud items
may not report a subtype in that list.

Use a broad type (image/* and/or video/*) for the PHOTO, VIDEO, and
PHOTO_OR_VIDEO contexts so the picker shows all visual media, matching
how other apps behave. Audio and document flows use the document browser
and keep the explicit accepted-types list.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Picking a category from the "Photos and videos" / "Other files"
disambiguation menu re-triggered the icon click, which fired the
MEDIA_PICKER_OPEN_DEVICE_LIBRARY event a second time (the first firing
happened when the menu was shown, before any picker opened). Split the
navigation out of clickIcon so the category re-trigger navigates without
tracking again.

Also tighten the {AUDIO, DOCUMENT} chooser branch to an exact set match
instead of a containsAll subset test, so only the disambiguation
"Other files" selection routes there.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ewModel

The Activity previously re-derived the visual-vs-other-files
classification to decide whether to show the disambiguation menu,
duplicating the allowedTypes taxonomy the ViewModel already owns. The
ViewModel now makes that decision and emits a dedicated
ShowSystemPickerTypeMenu action; the Activity just renders the menu.

This also corrects the "device library opened" analytics timing: the
ambiguous tap now shows the menu without tracking, and the open is
tracked when the user picks a category (the point at which a picker
actually opens), so dismissing the menu no longer counts as an open.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Update the "all supported files" test to expect the new
ShowSystemPickerTypeMenu action, and add coverage for choosing a
category (photos/videos -> PHOTO_OR_VIDEO, other files -> MEDIA_FILE)
and for the device-library open being tracked on category choice rather
than when the disambiguation menu is shown.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…rator

Move the allowedTypes -> (ChooserContext, MIME types) mapping and the
visual-vs-other-files ambiguity check out of MediaPickerViewModel into a
new SystemPickerResolver. This keeps the ViewModel under detekt's
LargeClass threshold (the disambiguation additions had pushed it over)
and makes the picker-type resolution independently testable.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…io/docs

The disambiguation "Other files" option scoped the document browser to
audio and documents only, which regressed the pre-disambiguation file
picker: an image or video reachable only by browsing the filesystem
(e.g. a freshly downloaded image in Downloads that the Photo Picker
hasn't surfaced) could no longer be selected. Send the full accepted-
types set so ACTION_OPEN_DOCUMENT shows images, videos, audio, and
documents, matching trunk's file picker. Remove the now-unused
audio+documents-only resolver branch.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Match the surrounding branches (including the OpenCameraForPhotos object)
which use `is` for their type checks, for consistency.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@dcalhoun dcalhoun force-pushed the feat/photo-picker-select branch from ef9cca3 to 9ad06dc Compare July 15, 2026 12:12
@dcalhoun dcalhoun marked this pull request as ready for review July 15, 2026 12:32
return
}
}
// Do we need tracking here?; review tracking need.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deemed a lingering comment that is no longer relevant from reviewing #13075.

navigateForIcon(icon)
}

private fun navigateForIcon(icon: MediaPickerIcon) {

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extracted to ensure analytic events occur on navigation, not simply tapping the icon button the menu bar. E.g., this avoids duplicate events when tapping "Choose from device" → "Photos and videos."

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extracted from MediaPickerViewModel to avoid Detekt warnings regarding class size.

Comment on lines +305 to +310
case PHOTO:
return new String[]{"image/*"};
case VIDEO:
return new String[]{"video/*"};
case PHOTO_OR_VIDEO:
return new String[]{"image/*", "video/*"};

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The broader MIME types ensure Google Photos does not display populated albums in its top-level view that then appear empty ("No photos yet" message) once navigating into an album itself.

@dcalhoun dcalhoun added this to the 27.0 milestone Jul 15, 2026
@dcalhoun dcalhoun requested a review from nbradbury July 15, 2026 12:46
@nbradbury

Copy link
Copy Markdown
Contributor

@dcalhoun I haven't tested this yet, but I did a Claude review which may be helpful to you.

review-pr23102-photo-picker-2026-07-15.pdf

@dcalhoun

dcalhoun commented Jul 15, 2026

Copy link
Copy Markdown
Member Author

@nbradbury thanks. Claude provided me similar feedback when I used it for review before requesting your own. Are there items you believe are worthwhile addressing?

1. The empty-albums fix misses the editor’s “Choose from device” flow
This could be true. However, I'll draw your attention to some major issues with this code that I uncovered during development and testing. Those issues prevented me from fully testing the referenced code. I captured this in a new Linear issue (CMM-2165) and welcome your help with that.

2. Broad types drop subtype filtering on the document-browser route
Aligned with the description, I also consider this a known trade-off. The file is rejected on upload rather being un-selectable.

3. Menu items hardcode type sets instead of deriving from the flow’s allowedTypes
Is this an actual issue? My perception is that contexts where a restricted MIME type is set circumvent the ambiguous dropdown menu altogether and navigate directly to the appropriate picker. Am I misunderstanding?

4. Two sources of truth for the visual-context MIME mapping
This cleanup suggestion seems valid. I don't perceive incorrectness in the suggestion at this time.

@nbradbury

Copy link
Copy Markdown
Contributor

@dcalhoun The way Claude worded the first one made it sound like a problem, but the rest sounded like nitpicks. I'm okay with leaving things as-is if you are.

@nbradbury

Copy link
Copy Markdown
Contributor

@dcalhoun This isn't working for me. I went to My Site > Media, tapped the + button and selected "Choose from device," but I still see the same "Choose from device" screen as I do prior to this PR.

@dcalhoun

Copy link
Copy Markdown
Member Author

@nbradbury it appears the testing instructions steps lack nuanced steps that are showcased in the screen recording in the PR description. One needs to tap the image icon button in the top-right corner once viewing the custom media grid (shown when tapping "Choose from device"). I'll update the testing instructions.

@nbradbury

nbradbury commented Jul 15, 2026 via email

Copy link
Copy Markdown
Contributor

…ypes

The broad image/* and video/* wildcards for the Photo Picker were decided
in WPMediaUtils.getMimeTypesForChooser, which overrode and discarded the
explicit subtype lists SystemPickerResolver had computed for the same
visual contexts. That left dead data in the resolver and duplicated the
ChooserContext -> MIME mapping across two files and two languages.

Move the wildcards into the resolver (the sole producer of
OpenSystemPicker) and drop the override so prepareChooserIntent uses the
resolved MIME types directly. Behavior is unchanged; add assertions
locking in image/* and image/*+video/* for the visual contexts.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@nbradbury

Copy link
Copy Markdown
Contributor

@dcalhoun When I add a file block, I don't see a "Choose from device" option. Am I missing a step again?

Screen_recording_20260715_124329.mp4

@nbradbury

Copy link
Copy Markdown
Contributor

Also, when adding an image to a post, should I see the image icon?

Screen_recording_20260715_124805.mp4

@dcalhoun

Copy link
Copy Markdown
Member Author

@nbradbury it appears you are using GutenbergKit. These changes do not impact GutenbergKit, only Gutenberg Mobile. I hoped the note in the PR description atop the testing instructions would clearly communicate that. Will you try Gutenberg Mobile instead?

@nbradbury

Copy link
Copy Markdown
Contributor

These changes do not impact GutenbergKit, only Gutenberg Mobile

Apologies, @dcalhoun - I think I was juggling too much along with this review. I'll approve the PR.

@nbradbury nbradbury left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants