Commit a2bb836f authored by Timothy Loh's avatar Timothy Loh Committed by Commit Bot

Detect the Crosh instance for the Crostini Terminal as a Crostini App.

This patch adds a override_app_name field to AppLaunchParams, which is
used when launching Crosh (for the Crostini Terminal) to set it to a
value that the CrostiniAppWindowShelfController can identify as a
Crostini App. Similar to v1 packaged apps which prefix with "_crx_", we
prefix with "_crostini_".

Previously, the opened window (crosh) would be separate to the Terminal
if it were pinned from the App List. Pinning the crosh to the shelf
resulted in an icon that only opened chrome://extensions. This patch
fixes this so the opened window is the same as a pinned terminal from
the App List.

Bug: 824549
Change-Id: Ifef0d5b476c5389639c0436ba272037710245ea6
Reviewed-on: https://chromium-review.googlesource.com/1034555Reviewed-by: default avatarNicholas Verne <nverne@chromium.org>
Reviewed-by: default avatarSteven Bennetts <stevenjb@chromium.org>
Reviewed-by: default avatarBen Wells <benwells@chromium.org>
Commit-Queue: Ben Wells <benwells@chromium.org>
Cr-Commit-Position: refs/heads/master@{#554725}
parent de283c36
...@@ -564,6 +564,8 @@ void CrostiniManager::LaunchContainerTerminal( ...@@ -564,6 +564,8 @@ void CrostiniManager::LaunchContainerTerminal(
AppLaunchParams launch_params( AppLaunchParams launch_params(
profile, crosh_extension, extensions::LAUNCH_CONTAINER_WINDOW, profile, crosh_extension, extensions::LAUNCH_CONTAINER_WINDOW,
WindowOpenDisposition::NEW_WINDOW, extensions::SOURCE_APP_LAUNCHER); WindowOpenDisposition::NEW_WINDOW, extensions::SOURCE_APP_LAUNCHER);
launch_params.override_app_name =
AppNameFromCrostiniAppId(kCrostiniTerminalId);
OpenApplicationWindow(launch_params, vsh_in_crosh_url); OpenApplicationWindow(launch_params, vsh_in_crosh_url);
} }
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "base/feature_list.h" #include "base/feature_list.h"
#include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_functions.h"
#include "base/strings/string_util.h"
#include "chrome/browser/chromeos/crostini/crostini_manager.h" #include "chrome/browser/chromeos/crostini/crostini_manager.h"
#include "chrome/browser/chromeos/crostini/crostini_pref_names.h" #include "chrome/browser/chromeos/crostini/crostini_pref_names.h"
#include "chrome/browser/chromeos/crostini/crostini_registry_service.h" #include "chrome/browser/chromeos/crostini/crostini_registry_service.h"
...@@ -19,7 +20,8 @@ ...@@ -19,7 +20,8 @@
namespace { namespace {
const char kCrostiniAppLaunchHistogram[] = "Crostini.AppLaunch"; constexpr char kCrostiniAppLaunchHistogram[] = "Crostini.AppLaunch";
constexpr char kCrostiniAppNamePrefix[] = "_crostini_";
// These values are persisted to logs. Entries should not be renumbered and // These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused. // numeric values should never be reused.
...@@ -125,3 +127,16 @@ std::string CryptohomeIdForProfile(Profile* profile) { ...@@ -125,3 +127,16 @@ std::string CryptohomeIdForProfile(Profile* profile) {
// Empty id means we're running in a test. // Empty id means we're running in a test.
return id.empty() ? "test" : id; return id.empty() ? "test" : id;
} }
std::string AppNameFromCrostiniAppId(const std::string& id) {
return kCrostiniAppNamePrefix + id;
}
base::Optional<std::string> CrostiniAppIdFromAppName(
const std::string& app_name) {
if (!base::StartsWith(app_name, kCrostiniAppNamePrefix,
base::CompareCase::SENSITIVE)) {
return base::nullopt;
}
return app_name.substr(strlen(kCrostiniAppNamePrefix));
}
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
#include <string> #include <string>
#include "base/optional.h"
class Profile; class Profile;
// Returns true if crostini is allowed to run. // Returns true if crostini is allowed to run.
...@@ -26,6 +28,15 @@ void LaunchCrostiniApp(Profile* profile, const std::string& app_id); ...@@ -26,6 +28,15 @@ void LaunchCrostiniApp(Profile* profile, const std::string& app_id);
std::string CryptohomeIdForProfile(Profile* profile); std::string CryptohomeIdForProfile(Profile* profile);
// The Terminal opens Crosh but overrides the Browser's app_name so that we can
// identify it as the Crostini Terminal. In the future, we will also use these
// for Crostini apps marked Terminal=true in their .desktop file.
std::string AppNameFromCrostiniAppId(const std::string& id);
// Returns nullopt for a non-Crostini app name.
base::Optional<std::string> CrostiniAppIdFromAppName(
const std::string& app_name);
constexpr char kCrostiniTerminalAppName[] = "Terminal"; constexpr char kCrostiniTerminalAppName[] = "Terminal";
// We can use any arbitrary well-formed extension id for the Terminal app, this // We can use any arbitrary well-formed extension id for the Terminal app, this
// is equal to GenerateId("Terminal"). // is equal to GenerateId("Terminal").
......
...@@ -12,12 +12,17 @@ ...@@ -12,12 +12,17 @@
#include "chrome/browser/chromeos/crostini/crostini_registry_service.h" #include "chrome/browser/chromeos/crostini/crostini_registry_service.h"
#include "chrome/browser/chromeos/crostini/crostini_registry_service_factory.h" #include "chrome/browser/chromeos/crostini/crostini_registry_service_factory.h"
#include "chrome/browser/chromeos/crostini/crostini_util.h" #include "chrome/browser/chromeos/crostini/crostini_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/ash/launcher/app_window_base.h" #include "chrome/browser/ui/ash/launcher/app_window_base.h"
#include "chrome/browser/ui/ash/launcher/app_window_launcher_item_controller.h" #include "chrome/browser/ui/ash/launcher/app_window_launcher_item_controller.h"
#include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h"
#include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h" #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/browser_window.h"
#include "components/exo/shell_surface.h" #include "components/exo/shell_surface.h"
#include "components/user_manager/user_manager.h" #include "components/user_manager/user_manager.h"
#include "extensions/browser/app_window/app_window.h"
#include "ui/aura/client/aura_constants.h" #include "ui/aura/client/aura_constants.h"
#include "ui/aura/env.h" #include "ui/aura/env.h"
#include "ui/base/base_window.h" #include "ui/base/base_window.h"
...@@ -31,9 +36,11 @@ CrostiniAppWindowShelfController::CrostiniAppWindowShelfController( ...@@ -31,9 +36,11 @@ CrostiniAppWindowShelfController::CrostiniAppWindowShelfController(
aura::Env* env = aura::Env::GetInstanceDontCreate(); aura::Env* env = aura::Env::GetInstanceDontCreate();
if (env) if (env)
env->AddObserver(this); env->AddObserver(this);
BrowserList::AddObserver(this);
} }
CrostiniAppWindowShelfController::~CrostiniAppWindowShelfController() { CrostiniAppWindowShelfController::~CrostiniAppWindowShelfController() {
BrowserList::RemoveObserver(this);
for (auto* window : observed_windows_) for (auto* window : observed_windows_)
window->RemoveObserver(this); window->RemoveObserver(this);
aura::Env* env = aura::Env::GetInstanceDontCreate(); aura::Env* env = aura::Env::GetInstanceDontCreate();
...@@ -141,6 +148,18 @@ void CrostiniAppWindowShelfController::OnWindowVisibilityChanged( ...@@ -141,6 +148,18 @@ void CrostiniAppWindowShelfController::OnWindowVisibilityChanged(
RegisterAppWindow(window, shelf_app_id); RegisterAppWindow(window, shelf_app_id);
} }
void CrostiniAppWindowShelfController::OnBrowserAdded(Browser* browser) {
// The Crostini Terminal opens in Crosh (a v1 App), but we override the
// Browser's app name so we can properly detect it.
if (!browser->is_type_popup() || !browser->is_app())
return;
base::Optional<std::string> app_id =
CrostiniAppIdFromAppName(browser->app_name());
if (!app_id)
return;
RegisterAppWindow(browser->window()->GetNativeWindow(), app_id.value());
}
void CrostiniAppWindowShelfController::RegisterAppWindow( void CrostiniAppWindowShelfController::RegisterAppWindow(
aura::Window* window, aura::Window* window,
const std::string& shelf_app_id) { const std::string& shelf_app_id) {
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "base/scoped_observer.h" #include "base/scoped_observer.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "chrome/browser/ui/ash/launcher/app_window_launcher_controller.h" #include "chrome/browser/ui/ash/launcher/app_window_launcher_controller.h"
#include "chrome/browser/ui/browser_list_observer.h"
#include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/bindings/binding.h"
#include "ui/aura/env_observer.h" #include "ui/aura/env_observer.h"
#include "ui/aura/window_observer.h" #include "ui/aura/window_observer.h"
...@@ -29,7 +30,8 @@ class ChromeLauncherController; ...@@ -29,7 +30,8 @@ class ChromeLauncherController;
// Chrome OS shelf. // Chrome OS shelf.
class CrostiniAppWindowShelfController : public AppWindowLauncherController, class CrostiniAppWindowShelfController : public AppWindowLauncherController,
public aura::EnvObserver, public aura::EnvObserver,
public aura::WindowObserver { public aura::WindowObserver,
public BrowserListObserver {
public: public:
explicit CrostiniAppWindowShelfController(ChromeLauncherController* owner); explicit CrostiniAppWindowShelfController(ChromeLauncherController* owner);
~CrostiniAppWindowShelfController() override; ~CrostiniAppWindowShelfController() override;
...@@ -44,6 +46,9 @@ class CrostiniAppWindowShelfController : public AppWindowLauncherController, ...@@ -44,6 +46,9 @@ class CrostiniAppWindowShelfController : public AppWindowLauncherController,
void OnWindowVisibilityChanged(aura::Window* window, bool visible) override; void OnWindowVisibilityChanged(aura::Window* window, bool visible) override;
void OnWindowDestroying(aura::Window* window) override; void OnWindowDestroying(aura::Window* window) override;
// BrowserListObserver:
void OnBrowserAdded(Browser* browser) override;
private: private:
using AuraWindowToAppWindow = using AuraWindowToAppWindow =
std::map<aura::Window*, std::unique_ptr<AppWindowBase>>; std::map<aura::Window*, std::unique_ptr<AppWindowBase>>;
......
...@@ -63,6 +63,9 @@ struct AppLaunchParams { ...@@ -63,6 +63,9 @@ struct AppLaunchParams {
// position and dimensions. // position and dimensions.
gfx::Rect override_bounds; gfx::Rect override_bounds;
// If non-empty, use override_app_name in place of generating one normally.
std::string override_app_name;
// If non-empty, information from the command line may be passed on to the // If non-empty, information from the command line may be passed on to the
// application. // application.
base::CommandLine command_line; base::CommandLine command_line;
......
...@@ -343,10 +343,13 @@ WebContents* OpenApplicationWindow(const AppLaunchParams& params, ...@@ -343,10 +343,13 @@ WebContents* OpenApplicationWindow(const AppLaunchParams& params,
Profile* const profile = params.profile; Profile* const profile = params.profile;
const Extension* const extension = GetExtension(params); const Extension* const extension = GetExtension(params);
std::string app_name = std::string app_name;
extension if (!params.override_app_name.empty())
? web_app::GenerateApplicationNameFromExtensionId(extension->id()) app_name = params.override_app_name;
: web_app::GenerateApplicationNameFromURL(url); else if (extension)
app_name = web_app::GenerateApplicationNameFromExtensionId(extension->id());
else
app_name = web_app::GenerateApplicationNameFromURL(url);
gfx::Rect initial_bounds; gfx::Rect initial_bounds;
if (!params.override_bounds.IsEmpty()) { if (!params.override_bounds.IsEmpty()) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment