0

Add shortcut to toggle the Gemini app

Bug: b:375245704
Change-Id: Ieb732b597a06f6889a33f6a384292eb60b90337a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5967254
Reviewed-by: David Padlipsky <dpad@google.com>
Commit-Queue: Michael Checo <michaelcheco@google.com>
Reviewed-by: Matthew Denton <mpdenton@chromium.org>
Reviewed-by: Jimmy Gong <jimmyxgong@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Reviewed-by: James Cook <jamescook@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1392974}
This commit is contained in:
Michael Checo
2024-12-06 17:06:40 +00:00
committed by Chromium LUCI CQ
parent b74451d27c
commit 833ea8ffb6
20 changed files with 94 additions and 2 deletions

@ -658,6 +658,10 @@ bool CanResizePipWindow() {
return Shell::Get()->pip_controller()->CanResizePip();
}
bool CanToggleGeminiApp() {
return features::IsAppLaunchShortcutEnabled();
}
bool CanScreenshot(bool take_screenshot) {
// |AcceleratorAction::kTakeScreenshot| is allowed when user session is
// blocked.
@ -1087,6 +1091,12 @@ void OpenHelp() {
NewWindowDelegate::GetInstance()->OpenGetHelp();
}
void ToggleGeminiApp() {
if (ash::features::IsAppLaunchShortcutEnabled()) {
NewWindowDelegate::GetInstance()->ToggleGeminiApp();
}
}
void PerformTilingWindowResize(AcceleratorAction action) {
if (!features::IsTilingWindowResizeEnabled()) {
return;

@ -111,6 +111,8 @@ ASH_EXPORT bool CanWindowSnap();
ASH_EXPORT bool CanResizePipWindow();
ASH_EXPORT bool CanToggleGeminiApp();
//////////////////////////////////////////////////////////////////////////////
// Accelerator commands.
// Note: These functions should be independent and not depend on ui::Accelerator
@ -327,6 +329,9 @@ ASH_EXPORT void ToggleClipboardHistory(bool is_plain_text_paste);
// triggered Quick Insert.
ASH_EXPORT void ToggleQuickInsert(base::TimeTicks accelerator_timestamp);
// Toggles Gemini.
ASH_EXPORT void ToggleGeminiApp();
// Enables Select to Speak if the feature is currently disabled. Does nothing if
// the feature is currently enabled.
ASH_EXPORT void EnableSelectToSpeak();

@ -1030,6 +1030,8 @@ bool AcceleratorControllerImpl::CanPerformAction(
return CanHandleLockButton(accelerator);
case AcceleratorAction::kResizePipWindow:
return accelerators::CanResizePipWindow();
case AcceleratorAction::kToggleGeminiApp:
return accelerators::CanToggleGeminiApp();
// The following are always enabled.
case AcceleratorAction::kBrightnessDown:
@ -1678,6 +1680,9 @@ void AcceleratorControllerImpl::PerformAction(
case AcceleratorAction::kResizePipWindow:
accelerators::ResizePipWindow();
break;
case AcceleratorAction::kToggleGeminiApp:
accelerators::ToggleGeminiApp();
break;
}
RecordActionUmaHistogram(action, accelerator);

@ -160,6 +160,11 @@ std::vector<ash::AcceleratorData> GetDefaultAccelerators() {
if (ash::debug::DeveloperAcceleratorsEnabled()) {
AppendAcceleratorData(accelerators, ash::kDeveloperAcceleratorData);
}
if (ash::features::IsAppLaunchShortcutEnabled()) {
AppendAcceleratorData(accelerators, ash::kGeminiAcceleratorData);
}
return accelerators;
}

@ -4306,6 +4306,9 @@ No devices connected.
<message name="IDS_ASH_ACCELERATOR_DESCRIPTION_OPEN_CROSH" desc="Label for accelerator action - Open Crosh window.">
Open Crosh window
</message>
<message name="IDS_ASH_ACCELERATOR_DESCRIPTION_TOGGLE_GEMINI_APP" desc="Label for accelerator action - Toggle Gemini App.">
Toggle Gemini
</message>
<message name="IDS_ASH_ACCELERATOR_DESCRIPTION_OPEN_DIAGNOSTICS" desc="Label for accelerator action - Open Diagnostics App.">
Open Diagnostics app
</message>

@ -0,0 +1 @@
fa7328a6b95120ad9c571390f3fb50477babe017

@ -171,6 +171,7 @@ namespace ash {
ACCELERATOR_ACTION_ENTRY(TilingWindowResizeDown) \
ACCELERATOR_ACTION_ENTRY(ToggleMouseKeys) \
ACCELERATOR_ACTION_ENTRY(ResizePipWindow) \
ACCELERATOR_ACTION_ENTRY(ToggleGeminiApp) \
/* Debug actions are kept at an offset.*/ \
/* This offset should be kept consistent with the enum*/ \
/* `AcceleratorAction` in*/ \

@ -18,12 +18,12 @@ namespace ash {
namespace {
// The total number of accelerator actions.
constexpr int kAcceleratorActionsTotalNum = 167;
constexpr int kAcceleratorActionsTotalNum = 168;
// The toal number of debug accelerators, these will not be used for hashing.
constexpr int kDebugAcceleratorActionsNum = 28;
// The hash of accelerator actions. Please update this when adding a new
// accelerator action.
constexpr char kAcceleratorActionsHash[] = "19f19f0e593d97ece036a1e5a9905135";
constexpr char kAcceleratorActionsHash[] = "bee5c18782483909ca5d43579d44442f";
// Define the mapping between an AcceleratorAction and its string name.
// Example:

@ -451,6 +451,13 @@ ASH_PUBLIC_EXPORT inline constexpr size_t
kTilingWindowResizeAcceleratorDataLength =
std::size(kTilingWindowResizeAcceleratorData);
ASH_PUBLIC_EXPORT inline constexpr AcceleratorData kGeminiAcceleratorData[] = {
{true, ui::VKEY_F23, ui::EF_COMMAND_DOWN | ui::EF_SHIFT_DOWN,
AcceleratorAction::kToggleGeminiApp},
};
ASH_PUBLIC_EXPORT inline constexpr size_t kGeminiAcceleratorDataLength =
std::size(kGeminiAcceleratorData);
// The public-facing interface for accelerator handling, which is Ash's duty to
// implement.
class ASH_PUBLIC_EXPORT AcceleratorController {

@ -135,6 +135,9 @@ class ASH_PUBLIC_EXPORT NewWindowDelegate {
// Opens a file on the local file system (which may be DriveFS).
virtual void OpenFile(const base::FilePath& file_path) = 0;
// Toggles Gemini.
virtual void ToggleGeminiApp() = 0;
protected:
NewWindowDelegate();
NewWindowDelegate(const NewWindowDelegate&) = delete;

@ -40,5 +40,6 @@ void TestNewWindowDelegate::OpenFeedbackPage(
void TestNewWindowDelegate::OpenPersonalizationHub() {}
void TestNewWindowDelegate::OpenCaptivePortalSignin(const GURL& url) {}
void TestNewWindowDelegate::OpenFile(const base::FilePath& file_path) {}
void TestNewWindowDelegate::ToggleGeminiApp() {}
} // namespace ash

@ -44,6 +44,7 @@ class ASH_PUBLIC_EXPORT TestNewWindowDelegate : public NewWindowDelegate {
void OpenPersonalizationHub() override;
void OpenCaptivePortalSignin(const GURL& url) override;
void OpenFile(const base::FilePath& file_path) override;
void ToggleGeminiApp() override;
};
} // namespace ash

@ -145,6 +145,7 @@ enum AcceleratorAction {
kTilingWindowResizeDown,
kToggleMouseKeys,
kResizePipWindow,
kToggleGeminiApp,
// The following are DEBUG actions with an offset. This is to keep the enum
// in sync with `AcceleratorActions` in ash/public/cpp/accelerator_actions.h.
kDebugClearUseKMeansPref = 9000,

@ -293,6 +293,8 @@ EnumTraits<mojom_accelerator_action, ash::AcceleratorAction>::ToMojom(
return mojom_accelerator_action::kMinimizeTopWindowOnBack;
case ash::AcceleratorAction::kResizePipWindow:
return mojom_accelerator_action::kResizePipWindow;
case ash::AcceleratorAction::kToggleGeminiApp:
return mojom_accelerator_action::kToggleGeminiApp;
case ash::AcceleratorAction::kDebugClearUseKMeansPref:
return mojom_accelerator_action::kDebugClearUseKMeansPref;
case ash::AcceleratorAction::kDebugKeyboardBacklightToggle:
@ -775,6 +777,9 @@ bool EnumTraits<mojom_accelerator_action, ash::AcceleratorAction>::FromMojom(
case mojom_accelerator_action::kResizePipWindow:
*out = ash::AcceleratorAction::kResizePipWindow;
return true;
case mojom_accelerator_action::kToggleGeminiApp:
*out = ash::AcceleratorAction::kToggleGeminiApp;
return true;
case mojom_accelerator_action::kDebugClearUseKMeansPref:
*out = ash::AcceleratorAction::kDebugClearUseKMeansPref;
return true;

@ -664,6 +664,14 @@ const AcceleratorLayoutMap& GetAcceleratorLayoutMap() {
/*locked=*/false,
mojom::AcceleratorLayoutStyle::kDefault,
mojom::AcceleratorSource::kAsh)},
{AcceleratorAction::kToggleGeminiApp,
AcceleratorLayoutDetails(
AcceleratorAction::kToggleGeminiApp,
IDS_ASH_ACCELERATOR_DESCRIPTION_TOGGLE_GEMINI_APP,
mojom::AcceleratorCategory::kGeneral,
mojom::AcceleratorSubcategory::kApps,
/*locked=*/false, mojom::AcceleratorLayoutStyle::kDefault,
mojom::AcceleratorSource::kAsh)},
// Device
{AcceleratorAction::kVolumeUp,

@ -310,6 +310,7 @@ inline constexpr uint32_t kAcceleratorLayouts[] = {
AcceleratorAction::kToggleResizeLockMenu,
AcceleratorAction::kShowTaskManager,
AcceleratorAction::kOpenCrosh,
AcceleratorAction::kToggleGeminiApp,
// Device
// Device > Media

@ -49,6 +49,7 @@
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/browser_navigator.h"
#include "chrome/browser/ui/browser_navigator_params.h"
#include "chrome/browser/ui/browser_window.h"
@ -165,6 +166,11 @@ bool OpenFilesSwa(Profile* const profile,
return true;
}
bool IsGeminiApp(Browser* browser) {
return web_app::GetAppIdFromApplicationName(browser->app_name()) ==
ash::kGeminiAppId;
}
} // namespace
ChromeNewWindowClient::ChromeNewWindowClient() {
@ -525,6 +531,32 @@ void ChromeNewWindowClient::OpenFile(const base::FilePath& file_path) {
platform_util::OpenOperationCallback());
}
void ChromeNewWindowClient::ToggleGeminiApp() {
Profile* const profile = ProfileManager::GetActiveUserProfile();
const auto& browsers = BrowserList::GetInstance()->OrderedByActivation();
auto it = std::find_if(browsers.begin(), browsers.end(),
[profile](Browser* browser) {
return browser->profile() == profile &&
browser->type() == Browser::Type::TYPE_APP &&
IsGeminiApp(browser);
});
Browser* active_browser = (it != browsers.end()) ? *it : nullptr;
if (!active_browser) {
apps::AppServiceProxyFactory::GetForProfile(profile)->Launch(
ash::kGeminiAppId, ui::EF_NONE, apps::LaunchSource::kFromKeyboard);
return;
}
BrowserWindow* app_window = active_browser->window();
if (app_window->IsActive()) {
app_window->Minimize();
} else {
app_window->Activate();
}
}
void ChromeNewWindowClient::LaunchCameraApp(const std::string& queries,
bool launch_in_dialog,
int32_t task_id) {

@ -50,6 +50,7 @@ class ChromeNewWindowClient : public ash::NewWindowDelegate,
void OpenPersonalizationHub() override;
void OpenCaptivePortalSignin(const GURL& url) override;
void OpenFile(const base::FilePath& file_path) override;
void ToggleGeminiApp() override;
// arc::ControlCameraAppDelegate:
void LaunchCameraApp(const std::string& queries,

@ -160,6 +160,7 @@ chromium-metrics-reviews@google.com.
<variant name="ToggleFullscreen"/>
<variant name="ToggleFullscreenMagnifier"/>
<variant name="ToggleGameDashboard"/>
<variant name="ToggleGeminiApp"/>
<variant name="ToggleHighContrast"/>
<variant name="ToggleImeMenuBubble"/>
<variant name="ToggleMaximized"/>

@ -189,6 +189,7 @@ chromium-metrics-reviews@google.com.
<int value="135" label="TilingWindowResizeDown"/>
<int value="136" label="ToggleMouseKeys"/>
<int value="137" label="ResizePipWindow"/>
<int value="138" label="ToggleGeminiApp"/>
<int value="9000" label="DebugClearUseKMeansPref"/>
<int value="9001" label="DebugKeyboardBacklightToggle"/>
<int value="9002" label="DebugMicrophoneMuteToggle"/>