blob: f37e700b5f6698d44b68f951ac15c785bc94f69a [file] [log] [blame]
// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/ash/login/kiosk_app_menu_controller.h"
#include <string>
#include <vector>
#include "ash/public/cpp/kiosk_app_menu.h"
#include "ash/public/cpp/login_screen.h"
#include "base/check.h"
#include "base/functional/bind.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/ash/app_mode/kiosk_app.h"
#include "chrome/browser/ash/app_mode/kiosk_app_launch_error.h"
#include "chrome/browser/ash/app_mode/kiosk_app_types.h"
#include "chrome/browser/ash/app_mode/kiosk_chrome_app_manager.h"
#include "chrome/browser/ash/app_mode/kiosk_controller.h"
#include "chrome/browser/ash/app_mode/web_app/web_kiosk_app_manager.h"
#include "chrome/browser/ui/ash/login/login_display_host.h"
#include "chrome/browser/ui/ash/login/login_screen_client_impl.h"
#include "extensions/grit/extensions_browser_resources.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/image/image_skia.h"
namespace ash {
namespace {
KioskAppId ToKioskAppId(const KioskAppMenuEntry& menu_entry) {
switch (menu_entry.type) {
case KioskAppMenuEntry::AppType::kWebApp:
return KioskAppId::ForWebApp(menu_entry.account_id);
case KioskAppMenuEntry::AppType::kChromeApp:
CHECK(menu_entry.chrome_app_id.has_value());
return KioskAppId::ForChromeApp(menu_entry.chrome_app_id.value(),
menu_entry.account_id);
case KioskAppMenuEntry::AppType::kIsolatedWebApp:
return KioskAppId::ForIsolatedWebApp(menu_entry.account_id);
}
}
KioskAppMenuEntry::AppType ToMenuEntryType(KioskAppType type) {
switch (type) {
case KioskAppType::kWebApp:
return KioskAppMenuEntry::AppType::kWebApp;
case KioskAppType::kChromeApp:
return KioskAppMenuEntry::AppType::kChromeApp;
case KioskAppType::kIsolatedWebApp:
return KioskAppMenuEntry::AppType::kIsolatedWebApp;
}
}
gfx::ImageSkia IconOrDefault(gfx::ImageSkia icon) {
return icon.isNull() ? *ui::ResourceBundle::GetSharedInstance()
.GetImageNamed(IDR_APP_DEFAULT_ICON)
.ToImageSkia()
: icon;
}
std::string GetMenuItemName(const KioskApp& app) {
if (!app.name().empty()) {
return std::string(app.name());
}
// The app name can be missing for an app that's received via policy
// before the CRX is loaded. Display the ChromeApp ID or URL in that case to
// prevent a blank menu item.
switch (app.id().type) {
case KioskAppType::kChromeApp:
case KioskAppType::kIsolatedWebApp:
return app.id().app_id.value();
case KioskAppType::kWebApp:
return app.url()->spec();
}
}
KioskAppMenuEntry ToMenuEntry(const KioskApp& app) {
return KioskAppMenuEntry(
ToMenuEntryType(app.id().type), app.id().account_id, app.id().app_id,
base::UTF8ToUTF16(GetMenuItemName(app)), IconOrDefault(app.icon()));
}
std::vector<KioskAppMenuEntry> BuildKioskAppMenuEntries() {
std::vector<KioskAppMenuEntry> menu_entries;
for (const KioskApp& app : KioskController::Get().GetApps()) {
menu_entries.push_back(ToMenuEntry(app));
}
return menu_entries;
}
} // namespace
KioskAppMenuController::KioskAppMenuController() {
kiosk_observations_.AddObservation(KioskChromeAppManager::Get());
kiosk_observations_.AddObservation(WebKioskAppManager::Get());
}
KioskAppMenuController::~KioskAppMenuController() = default;
void KioskAppMenuController::OnKioskAppDataChanged(const std::string& app_id) {
SendKioskApps();
ConfigureKioskCallbacks();
}
void KioskAppMenuController::OnKioskAppDataLoadFailure(
const std::string& app_id) {
SendKioskApps();
}
void KioskAppMenuController::OnKioskAppsSettingsChanged() {
SendKioskApps();
}
void KioskAppMenuController::SendKioskApps() {
if (!LoginScreenClientImpl::HasInstance()) {
return;
}
KioskAppMenu::Get()->SetKioskApps(BuildKioskAppMenuEntries());
KioskAppLaunchError::Error error = KioskAppLaunchError::Get();
if (error == KioskAppLaunchError::Error::kNone) {
return;
}
// Clear any old pending Kiosk launch errors
KioskAppLaunchError::RecordMetricAndClear();
LoginScreen::Get()->ShowKioskAppError(
KioskAppLaunchError::GetErrorMessage(error));
}
void KioskAppMenuController::ConfigureKioskCallbacks() {
KioskAppMenu::Get()->ConfigureKioskCallbacks(
base::BindRepeating(&KioskAppMenuController::LaunchApp,
weak_factory_.GetWeakPtr()),
base::BindRepeating(&KioskAppMenuController::OnMenuWillShow,
weak_factory_.GetWeakPtr()));
}
void KioskAppMenuController::LaunchApp(const KioskAppMenuEntry& menu_entry) {
LoginDisplayHost::default_host()->StartKiosk(ToKioskAppId(menu_entry),
/*is_auto_launch=*/false);
}
void KioskAppMenuController::OnMenuWillShow() {
// Web app based kiosk app will want to load their icons.
WebKioskAppManager::Get()->LoadIcons();
}
} // namespace ash