Skip to content

LGC-2026-07-22T045642

@karlenDimla karlenDimla tagged this 21 Jul 16:37
Task/Issue URL:
https://app.asana.com/1/137249556945/project/488551667048375/task/1216706777618509?focus=true
Tech Design URL (if applicable): 

### Description
Stop firing the contextual Duck.ai sheet dismissed pixel when the sheet
pauses to show a picker (file, image, or camera). The pixel now only
fires on a genuine dismissal.
- onPause() skips onSheetClosed() while an upload is pending
(pendingUploadTask non-null), since that pause is caused by opening a
picker rather than the user dismissing the sheet.
- Keep the bottom-row icons visible when the input is focused after
adding any attachment. attachmentChanged() now re-evaluates the bottom
row so its visibility no longer goes stale on attachment add/clear.


### Steps to test this PR
SETUP
- [x] Enable `contextualNativeInput` (native input widget) via feature
flag inventory (disabled by default)
  - [x] Logcat filtered for `m_aichat_contextual_sheet_dismissed`
  - [x] Open a web page, then open the contextual Duck.ai sheet from it

  1. Launch file picker from the sheet
- [x] Trigger a file upload that routes to the system file picker
(non-image/video accept types)
- [x] While the picker is open,
m_aichat_contextual_sheet_dismissed_count is NOT fired
  - [x] m_aichat_contextual_sheet_dismissed_daily is NOT fired
- [x] Cancel the picker → the contextual sheet is still open with prior
state intact
- [x] Pick a file → the file is delivered to the input/webview and the
sheet is still open

  2. Launch image gallery picker from the sheet

- [x] Trigger an image attachment and choose Gallery from the
camera/gallery disambiguation sheet
- [x] While the gallery picker is open, the dismissed pixels are NOT
fired
- [x] Select an image → it is attached and the contextual sheet is still
open

  3. Launch camera capture from the sheet
- [x] Trigger an image attachment and choose Camera from the
disambiguation sheet
  - [x] While the camera app is open, the dismissed pixels are NOT fired
- [x] Capture / cancel → return to the contextual sheet with the
dismissed pixels still NOT fired

  4. Cancel the camera/gallery disambiguation sheet
- [x] Trigger an image attachment, then dismiss the disambiguation
bottom sheet without choosing
- [x] The contextual sheet remains open and the dismissed pixels are NOT
fired (this dialog does not pause the fragment)

  5. Genuine dismissal — swipe / hide the sheet
- [x] With no picker involved, swipe the sheet down to hidden
(STATE_HIDDEN)
  - [x] m_aichat_contextual_sheet_dismissed_count IS fired
- [x] m_aichat_contextual_sheet_dismissed_daily IS fired (first time
that day)

  6. Genuine dismissal — background the app (no picker)
- [x] With the sheet open and no upload pending, send the app to
background (Home)
  - [x] The dismissed pixels ARE fired on pause

  7. Bottom row visibility after adding an attachment (input focused)
  - [x] With the input focused, add an image/file attachment.
  - [ ] Re-focus input after attaching
- [ ] The bottom-row icons (attach, options, tools, model/reasoning
picker, send) ARE still visible
- [ ] Bottom-row icons do not disappear or become stale after the
attachment appears

  8. Bottom row visibility after clearing an attachment (input focused)
- [ ] With an attachment present and input focused, remove the
attachment
- [ ] After the attachment is cleared, the bottom-row icons ARE still
visible while the input remains focused


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Changes when contextual dismiss analytics and `onContextualClosed` run
(lifecycle vs sheet hidden only), which can affect metrics and session
persistence; file upload callback timing is localized but easy to
regress.
> 
> **Overview**
> Fixes **false contextual sheet dismissed** analytics when the user
opens a system file picker from the contextual Duck.ai sheet, and
tightens **file upload result** handling.
> 
> **`onPause()`** no longer calls `viewModel.onSheetClosed()`.
Sheet-dismiss pixels and related cleanup
(`reportContextualSheetDismissed()`, etc.) now run only when the bottom
sheet reaches **`STATE_HIDDEN`** via the existing `BottomSheetCallback`,
so pausing the fragment to show a picker is not treated as dismissing
the sheet.
> 
> In **`handleFileUploadResult`**, the pending `ValueCallback` is copied
to a local variable and **`pendingUploadTask` is cleared immediately**
before delivering URIs or `null`, so the callback is completed once and
is not tied to mutable pending state for the rest of the method.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
0f6b6e80de4cdd1e8ec961be479896e3c85075db. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Assets 2
Loading