Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions docs/feature-checklist.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ Flagship feature. C++ services + `dao://dao-agent` WebUI + vendor runtime.

| ✔ | Feature | Patch(es) / Source | Risk | Verify after upgrade |
|---|---------|--------------------|------|----------------------|
| ☐ | Auto-PiP for *any* video site + Document-PiP interception on configured sites | `picture_in_picture/auto_picture_in_picture_tab_helper.{cc,h}.patch`, `src/dao/browser/pip/dao_pip_interceptor.{cc,h}` | 🔴 | Tab-switch on a plain `<video>` page auto-opens PiP; configured site opens Document-PiP and does NOT immediately close; returning to its opener tab closes a manually or automatically opened window and restores the moved player element to the original page |
| ☐ | Auto-PiP for *any* video site + Document-PiP interception on configured sites | `picture_in_picture/auto_picture_in_picture_tab_helper.{cc,h}.patch`, `src/dao/browser/pip/dao_pip_interceptor.{cc,h}` | 🔴 | With automatic PiP enabled, tab-switch on a plain `<video>` page auto-opens PiP and configured sites open Document-PiP; disable it in **You and Dao** and confirm tab-switch plus window hide/minimize no longer auto-open PiP while manual PiP still works; returning to the opener closes a manually or automatically opened window and restores the moved player element |
| ☐ | Per-site Document-PiP bounds persistence + no permission overlay | `picture_in_picture/picture_in_picture_window_manager.{cc,h}.patch` | 🔴 | Resize/close/reopen restores size; **no permission bubble** (security-relevant removal — review each rebase) |
| ☐ | Floating auto-hiding Document-PiP top bar (separate overlay widget, hover fade, corner-resize, drag-move) | `views/frame/picture_in_picture_browser_frame_view.{cc,h}.patch` | 🔴 | Top bar hidden initially, fades on hover; drag moves; corner drags resize; content fills width. **Confirm `render_active_` default stays `false`** |
| ☐ | PiP overlay button re-layout (back-to-tab top-left, minimize adjacent) | `views/overlay/back_to_tab_button.cc.patch`, `minimize_button.cc.patch` | 🟢 | Buttons at top-left, no overlap |
Expand All @@ -157,7 +157,7 @@ Flagship feature. C++ services + `dao://dao-agent` WebUI + vendor runtime.
| ☐ | macOS history-swipe overlay clipped | `renderer_host/chrome_render_widget_host_view_mac_delegate.mm.patch` | 🟢 | Back/forward swipe overlay stays clipped |
| ☐ | Dao dark blue-gray PiP window theme | `ui/color/chrome_color_mixer.cc.patch` | 🟡 | PiP uses Dao colors; check newly-added `kColorPipWindow*` tokens for unthemed defaults |
| ☐ | Media progress bar fills flush to playhead | `components/global_media_controls/.../media_progress_view.cc.patch` | 🟢 | No gap between fill and indicator |
| ☐ | PiP interceptor + auto-PiP visibility tab helpers | `ui/tab_helpers.cc.patch` + `src/dao/browser/pip/` | 🟢 | Interception + minimize-triggered auto-PiP work; transient opener visibility keeps Document PiP open, while selecting the opener closes it and restores its target |
| ☐ | PiP interceptor + auto-PiP visibility tab helpers | `ui/tab_helpers.cc.patch` + `src/dao/browser/pip/` | 🟢 | Interception + minimize-triggered auto-PiP work when the native automatic PiP content setting is not blocked; transient opener visibility keeps Document PiP open, while selecting the opener closes it and restores its target |
| ☐ | Doc-PiP permission-prompt / SODA-failure-log flags enabled | `media/base/media_switches.cc.patch` | 🟡 | Both flags still exist + default enabled |

> **Highest-risk trio:** auto-PiP eligibility rewrite, window-manager overlay/bounds
Expand Down Expand Up @@ -259,12 +259,12 @@ Not in `src/patches/`. Import mechanically rewrites `chrome://`→`dao://` in:
|---|---------|-----------|------|--------|
| ☐ | Open Design continuous settings overview | `resources/settings/settings_{ui,main,menu}/`, top-level `*_page_index.html.patch` files, `settings_shared.css.patch`, `settings_page/settings_section.html.patch` | 🟡 | Verify the 184px table of contents and content share one background; all visible top-level sections render continuously in a 680px column with 30px spacing; nested page-index views have non-zero flow height and never overlap the following section; menu clicks and scroll position synchronize selection/hash without Router navigation; legacy top-level paths normalize to hashes; secondary routes remain independent and restore overview context; the real `#searchField` Polymer key is wired; entering search captures overview scroll once, shows only matching menu IDs, clears selection on zero results, restores the full menu and captured scroll on clear, and never navigates top-level routes; href, `pageVisibility_`, pref, policy, toggle, and link-row inventories remain intact. Run the Settings main/menu/UI and local redesign contract tests in light, dark, and narrow layouts. |
| ☐ | Compact Agent overview entry and five-section secondary page | `resources/settings/dao_page/dao_agent_page*.patch`, `settings_main/`, `settings_menu/`, `lazy_load.ts.patch`, `route.ts.patch`, `router_dao.ts.patch` | 🟡 | Verify the continuous overview renders one compact Agent entry and no full Agent form; `#agent` scrolls to that entry; activating it or navigating directly to `/agent` opens only the secondary detail view; Back restores the overview and Agent scroll context; the Agent menu item remains selected on the child route; Settings search finds the compact entry; and the detail page renders exactly Model and connection, Behavior and context, Capabilities, Learning and analysis, and Data and management in that order with no section rail or tabs. Check mouse and keyboard activation, heading focus, visible focus, reduced motion, light/dark themes, desktop, and below 760 px. |
| ☐ | Dao settings page UI (Profile feature controls + global MCP card + enhanced-PiP preview) | `resources/settings/dao_page/dao_page.{html,ts}.patch` (new files), `src/dao/.../mcp/dao_mcp_settings_handler.{h,cc}` | 🟡 | Page renders the Profile-backed feature toggles plus an independent MCP header/connection/enabled-only-setup card. Verify aligned, narrow-width-stacking setup controls; lease-only client/Stop controls; whitespace-preserving preview; native three-space Generic MCP JSON identical to copied content; malformed JSON failure without clipboard change; dynamic copy feedback; no standalone configuration action; and the animated PiP preview |
| ☐ | Dao settings page UI (Profile feature controls + global MCP card + automatic-PiP control + enhanced-PiP preview) | `resources/settings/dao_page/dao_page.{html,ts}.patch` (new files), `src/dao/.../mcp/dao_mcp_settings_handler.{h,cc}` | 🟡 | Page renders the Profile-backed feature toggles, the native automatic PiP content setting, and an independent MCP header/connection/enabled-only-setup card. Verify the automatic PiP switch reads/writes `ASK`/`BLOCK` and remains independent from enhanced PiP; verify aligned, narrow-width-stacking setup controls; lease-only client/Stop controls; whitespace-preserving preview; native three-space Generic MCP JSON identical to copied content; malformed JSON failure without clipboard change; dynamic copy feedback; no standalone configuration action; and the animated PiP preview |
| ☐ | Dao settings prefs exposed through SettingsPrivate allowlist | `extensions/api/settings_private/prefs_util.cc.patch`, `src/dao/browser/dao_pref_names.*` | 🟡 | Toggles read/write `dao.little_dao_enabled`, `dao.enhanced_pip_enabled`, and `dao.enhanced_command_bar_suggestions_enabled` without console errors |
| ☐ | Page registered in build | `resources/settings/BUILD.gn.patch` | 🟢 | `dao_page.ts` compiled/bundled |
| ☐ | `/dao` route + visibility + menu item + main view slot + export | `route.ts`, `router.ts`, `router_dao.ts`, `page_visibility.ts`, `settings_main/settings_main.{html,ts}`, `settings_menu/settings_menu.html`, `settings.ts` patches | 🟡 | `/dao` resolves; "You and Dao" menu item shows/hides; view renders |
| ☐ | Dao settings localized strings | `webui/settings/settings_localized_strings_provider.cc.patch`, `app/settings_strings.grdp.patch`, `app/resources/generated_resources_zh-CN.xtb.patch` | 🟡 / 🔴 | Dao Profile, MCP status, and quick-setup messages are present in the merged GRDP/provider patches and the hand-authored zh-CN XTB patch; grit build passes |
| ☐ | Settings WebUI test | `test/data/webui/settings/{BUILD.gn,dao_page_test.ts}.patch` | 🟡 | `settings-dao-page`, `routes.DAO`, Profile-backed `dao.*` prefs, unified MCP card sections, global MCP status/action rendering, responsive setup controls, multiline Generic MCP JSON preview and dynamic copy, stale-response handling, standalone-copy removal, and browser-proxy calls are covered |
| ☐ | Dao settings localized strings | `webui/settings/settings_localized_strings_provider.cc.patch`, `app/settings_strings.grdp.patch`, `app/resources/generated_resources_zh-CN.xtb.patch` | 🟡 / 🔴 | Dao Profile, automatic PiP, MCP status, and quick-setup messages are present in the merged GRDP/provider patches and the hand-authored zh-CN XTB patch; grit build passes |
| ☐ | Settings WebUI test | `test/data/webui/settings/{BUILD.gn,dao_page_test.ts}.patch` | 🟡 | `settings-dao-page`, `routes.DAO`, Profile-backed `dao.*` prefs, native automatic PiP `ASK`/`BLOCK`, unified MCP card sections, global MCP status/action rendering, responsive setup controls, multiline Generic MCP JSON preview and dynamic copy, stale-response handling, standalone-copy removal, and browser-proxy calls are covered |

### 8.2 macOS Sparkle updater + sign-in/sync disable (feature cluster B)

Expand Down
2 changes: 1 addition & 1 deletion docs/features.md
Original file line number Diff line number Diff line change
Expand Up @@ -590,7 +590,7 @@ Built on Chromium's native PiP, adds a Document-PiP interception layer plus seve
- **DaoPipSiteRules** — Site rules loaded from `pip_site_rules.json`

### 3.2 Auto-PiP triggers
- **DaoAutoPipVisibilityHelper** (`browser/dao_auto_pip_visibility_helper.{h,cc}`) — Watches window-visibility changes (minimize, hide) and triggers auto-PiP for the active tab's playing video; complements Chromium's `AutoPictureInPictureTabHelper` (which only handles tab switching)
- **DaoAutoPipVisibilityHelper** (`browser/dao_auto_pip_visibility_helper.{h,cc}`) — Watches window-visibility changes (minimize, hide) and triggers auto-PiP for the active tab's playing video; complements Chromium's `AutoPictureInPictureTabHelper` (which handles tab switching). Both paths obey Chromium's native automatic Picture-in-Picture content setting, exposed as a switch on **You and Dao**
- Patches: `auto_picture_in_picture_tab_helper.cc.patch`, `picture_in_picture_window_manager.cc.patch`

### 3.3 PiP window chrome
Expand Down
19 changes: 19 additions & 0 deletions src/dao/browser/dao_auto_pip_visibility_helper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,18 @@

#include "dao/browser/dao_auto_pip_visibility_helper.h"

#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
#include "chrome/browser/picture_in_picture/picture_in_picture_window_manager.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "components/content_settings/core/common/content_settings.h"
#include "components/content_settings/core/common/content_settings_types.h"
#include "content/public/browser/media_session.h"
#include "dao/browser/pip/dao_pip_interceptor.h"
#include "url/gurl.h"

namespace dao {

Expand All @@ -20,6 +26,16 @@ DaoAutoPipVisibilityHelper::DaoAutoPipVisibilityHelper(

DaoAutoPipVisibilityHelper::~DaoAutoPipVisibilityHelper() = default;

bool DaoAutoPipVisibilityHelper::IsAutoPictureInPictureAllowed() const {
Profile* profile =
Profile::FromBrowserContext(web_contents()->GetBrowserContext());
const GURL& url = web_contents()->GetLastCommittedURL();
return HostContentSettingsMapFactory::GetForProfile(profile)
->GetContentSetting(
url, url, ContentSettingsType::AUTO_PICTURE_IN_PICTURE) !=
CONTENT_SETTING_BLOCK;
}

void DaoAutoPipVisibilityHelper::OnVisibilityChanged(
content::Visibility visibility) {
if (visibility == content::Visibility::HIDDEN ||
Expand All @@ -36,6 +52,9 @@ void DaoAutoPipVisibilityHelper::OnVisibilityChanged(
if (active_index != our_index) {
return; // Not the active tab, skip (tab switch handled elsewhere).
}
if (!IsAutoPictureInPictureAllowed()) {
return;
}

// Check if already in PiP.
if (triggered_pip_) {
Expand Down
4 changes: 4 additions & 0 deletions src/dao/browser/dao_auto_pip_visibility_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#ifndef DAO_BROWSER_DAO_AUTO_PIP_VISIBILITY_HELPER_H_
#define DAO_BROWSER_DAO_AUTO_PIP_VISIBILITY_HELPER_H_

#include "base/gtest_prod_util.h"
#include "base/memory/weak_ptr.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/browser/web_contents_user_data.h"
Expand All @@ -26,8 +27,11 @@ class DaoAutoPipVisibilityHelper

private:
friend class content::WebContentsUserData<DaoAutoPipVisibilityHelper>;
FRIEND_TEST_ALL_PREFIXES(DaoAutoPipContentSettingBrowserTest,
RespectsBlockedSetting);
explicit DaoAutoPipVisibilityHelper(content::WebContents* web_contents);

bool IsAutoPictureInPictureAllowed() const;
void OnDocumentPipResult(bool success);

bool triggered_pip_ = false;
Expand Down
29 changes: 29 additions & 0 deletions src/dao/browser/ui/views/dao_browser_browsertest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "base/values.h"
#include "build/build_config.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
#include "chrome/browser/extensions/chrome_test_extension_loader.h"
#include "chrome/browser/extensions/extension_action_dispatcher.h"
#include "chrome/browser/extensions/extension_tab_util.h"
Expand Down Expand Up @@ -79,6 +80,9 @@
#include "chrome/test/base/search_test_utils.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/constrained_window/constrained_window_views.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "components/content_settings/core/common/content_settings.h"
#include "components/content_settings/core/common/content_settings_types.h"
#include "components/download/public/common/download_item.h"
#include "components/omnibox/browser/autocomplete_match.h"
#include "components/omnibox/browser/autocomplete_provider.h"
Expand Down Expand Up @@ -7377,6 +7381,31 @@ IN_PROC_BROWSER_TEST_F(DaoAutoPipVisibilityHelperBrowserTest,
EXPECT_EQ(helper, dao::DaoAutoPipVisibilityHelper::FromWebContents(contents));
}

namespace dao {

using DaoAutoPipContentSettingBrowserTest = InProcessBrowserTest;

IN_PROC_BROWSER_TEST_F(DaoAutoPipContentSettingBrowserTest,
RespectsBlockedSetting) {
content::WebContents* contents =
browser()->tab_strip_model()->GetActiveWebContents();
ASSERT_NE(nullptr, contents);
auto* helper = DaoAutoPipVisibilityHelper::FromWebContents(contents);
ASSERT_NE(nullptr, helper);

HostContentSettingsMap* settings =
HostContentSettingsMapFactory::GetForProfile(browser()->profile());
settings->SetDefaultContentSetting(
ContentSettingsType::AUTO_PICTURE_IN_PICTURE, CONTENT_SETTING_BLOCK);
EXPECT_FALSE(helper->IsAutoPictureInPictureAllowed());

settings->SetDefaultContentSetting(
ContentSettingsType::AUTO_PICTURE_IN_PICTURE, CONTENT_SETTING_ASK);
EXPECT_TRUE(helper->IsAutoPictureInPictureAllowed());
}

} // namespace dao

// =============================================================================
// DaoWebstoreBrandingTabHelperBrowserTest
//
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
diff --git a/chrome/app/resources/generated_resources_zh-CN.xtb b/chrome/app/resources/generated_resources_zh-CN.xtb
--- a/chrome/app/resources/generated_resources_zh-CN.xtb
+++ b/chrome/app/resources/generated_resources_zh-CN.xtb
@@ -1,6 +1,123 @@
@@ -1,6 +1,125 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="zh-CN">
+<translation id="42079359526797400">增强的画中画 (PIP)</translation>
+<translation id="2382779221361494104">自动画中画 (PIP)</translation>
+<translation id="5282350383463890461">播放中的视频进入后台时,自动打开画中画</translation>
+<translation id="532636291227772742">快速接入</translation>
+<translation id="6649293836182248224">选择一个选项,然后复制并使用下方显示的命令或配置。</translation>
+<translation id="6304318647555713317">客户端</translation>
Expand Down
8 changes: 7 additions & 1 deletion src/patches/chrome/app/settings_strings.grdp.patch
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp
Sites listed below follow a custom setting instead of the default
</message>
<message name="IDS_SETTINGS_SITE_DATA_PAGE_ALLOW_EXCEPTIONS_SUB_HEADING" desc="1 of 3. A label within 'Customized behaviors' that allows for exceptions to the 'On-device site data' setting. This label and the list of sites that can appear beneath it is only relevant if the user has chosen to not allow 'on-device site data' as the default value above.">
@@ -3836,7 +3836,511 @@
@@ -3836,7 +3836,517 @@
<!-- Sync / People Page -->
<message name="IDS_SETTINGS_PEOPLE" desc="Name of the settings page which manages the user's relationship to Google.">
You and Google
Expand Down Expand Up @@ -634,6 +634,12 @@ diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp
+ <message name="IDS_SETTINGS_STALE_TAB_EXPIRATION_HOURS_ERROR" desc="Error shown when the stale tab expiration input is outside its supported integer range.">
+ Enter a whole number from 1 to 720
+ </message>
+ <message name="IDS_SETTINGS_AUTO_PIP_ENABLED_LABEL" desc="Label for the setting that enables or disables automatic Picture-in-Picture when a playing video moves to the background.">
+ Automatic Picture-in-Picture (PIP)
+ </message>
+ <message name="IDS_SETTINGS_AUTO_PIP_ENABLED_SUB_LABEL" desc="Description for the setting that automatically opens Picture-in-Picture when a playing video moves to the background.">
+ Open Picture-in-Picture automatically when a playing video moves to the background
+ </message>
+ <message name="IDS_SETTINGS_ENHANCED_PIP_ENABLED_LABEL" desc="Label for the setting that enables or disables Dao's custom Document Picture-in-Picture behavior on supported video sites.">
+ Enhanced Picture-in-Picture (PIP)
+ </message>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ new file mode 100644
index 0000000000..0000000001
--- /dev/null
+++ b/chrome/browser/resources/settings/dao_page/dao_page.html
@@ -0,0 +1,630 @@
@@ -0,0 +1,637 @@
+<style include="settings-shared">
+ .dao-mcp-settings {
+ border: 1px solid var(--cr-separator-color);
Expand Down Expand Up @@ -476,6 +476,13 @@ index 0000000000..0000000001
+ </span>
+ </cr-input>
+ </div>
+ <settings-toggle-button id="autoPipEnabled"
+ pref="{{autoPipEnabledPref_}}"
+ no-set-pref
+ label="$i18n{autoPipEnabledLabel}"
+ sub-label="$i18n{autoPipEnabledSubLabel}"
+ on-settings-boolean-control-change="onAutoPipEnabledChange_">
+ </settings-toggle-button>
+ <settings-toggle-button id="enhancedPipEnabled"
+ pref="{{prefs.dao.enhanced_pip_enabled}}"
+ label="$i18n{enhancedPipEnabledLabel}"
Expand Down
Loading
Loading