blob: 0494b51ecec10a993dc54eaa3e7611881111989a [file] [log] [blame]
// Copyright 2022 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/chromeos/office_web_app/office_web_app.h"
#include "base/functional/bind.h"
#include "base/metrics/histogram_macros.h"
#include "chrome/browser/apps/app_service/app_service_proxy.h"
#include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
#include "chrome/browser/web_applications/external_install_options.h"
#include "chrome/browser/web_applications/externally_managed_app_manager.h"
#include "chrome/browser/web_applications/mojom/user_display_mode.mojom.h"
#include "chrome/browser/web_applications/web_app_constants.h"
#include "chrome/browser/web_applications/web_app_helpers.h"
#include "chrome/browser/web_applications/web_app_icon_generator.h"
#include "chrome/browser/web_applications/web_app_install_info.h"
#include "chrome/browser/web_applications/web_app_provider.h"
#include "chrome/browser/web_applications/web_app_registrar.h"
#include "chrome/grit/generated_resources.h"
#include "chrome/grit/office_web_app_resources.h"
#include "components/webapps/browser/install_result_code.h"
#include "components/webapps/browser/installable/installable_metrics.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "url/gurl.h"
namespace chromeos {
const char kMicrosoft365WebAppUrl[] =
"https://www.microsoft365.com/?from=Homescreen";
namespace {
constexpr char kMicrosoft365FallbackName[] = "Microsoft 365";
void OnOfficeWebAppInstalledOffline(
Profile* profile,
base::OnceCallback<void(webapps::InstallResultCode)> callback,
const GURL& install_url,
web_app::ExternallyManagedAppManager::InstallResult result) {
UMA_HISTOGRAM_ENUMERATION(
"FileBrowser.OfficeFiles.Setup.OfficeWebAppOfflineInstallation",
result.code);
if (webapps::IsSuccess(result.code)) {
auto* proxy = apps::AppServiceProxyFactory::GetForProfile(profile);
proxy->SetSupportedLinksPreference(*result.app_id);
} else {
LOG(ERROR) << "Office web app offline installation failure: "
<< result.code;
}
std::move(callback).Run(result.code);
}
void InstallMicrosoft365Offline(
Profile* profile,
base::OnceCallback<void(webapps::InstallResultCode)> callback) {
auto* provider = web_app::WebAppProvider::GetForWebApps(profile);
DCHECK(provider);
// Manually install using the manifest at
// https://www.microsoft365.com/webmanifest.json.
web_app::ExternalInstallOptions options(
GURL(kMicrosoft365WebAppUrl),
web_app::mojom::UserDisplayMode::kStandalone,
web_app::ExternalInstallSource::kInternalMicrosoft365Setup);
options.fallback_app_name = kMicrosoft365FallbackName;
options.add_to_quick_launch_bar = false;
options.only_use_app_info_factory = true;
options.app_info_factory = base::BindRepeating([]() {
GURL start_url = GURL(kMicrosoft365WebAppUrl);
webapps::ManifestId manifest_id =
web_app::GenerateManifestIdFromStartUrlOnly(start_url);
auto info =
std::make_unique<web_app::WebAppInstallInfo>(manifest_id, start_url);
info->title =
l10n_util::GetStringUTF16(IDS_OFFICE_FILE_HANDLER_APP_MICROSOFT);
info->scope = GURL("/");
info->display_mode = web_app::DisplayMode::kStandalone;
auto image = ui::ResourceBundle::GetSharedInstance().GetImageNamed(
IDR_OFFICE_WEB_APP_ICONS_OFFICE_192_PNG);
info->icon_bitmaps.any[192] = image.AsBitmap();
info->background_color = 0xFFD53A00;
info->theme_color = 0xFFD53A00;
return info;
});
provider->externally_managed_app_manager().InstallNow(
std::move(options), base::BindOnce(&OnOfficeWebAppInstalledOffline,
profile, std::move(callback)));
}
void OnOfficeWebAppInstalled(
Profile* profile,
base::OnceCallback<void(webapps::InstallResultCode)> callback,
const GURL& install_url,
web_app::ExternallyManagedAppManager::InstallResult result) {
UMA_HISTOGRAM_ENUMERATION(
"FileBrowser.OfficeFiles.Setup.OfficeWebAppInstallation", result.code);
if (webapps::IsSuccess(result.code)) {
auto* proxy = apps::AppServiceProxyFactory::GetForProfile(profile);
proxy->SetSupportedLinksPreference(*result.app_id);
std::move(callback).Run(result.code);
return;
}
// Fallback to an offline install.
LOG(ERROR) << "Office web app installation failure: " << result.code
<< " attempting offline installation";
InstallMicrosoft365Offline(profile, std::move(callback));
}
} // namespace
void InstallMicrosoft365(
Profile* profile,
base::OnceCallback<void(webapps::InstallResultCode)> callback) {
auto* provider = web_app::WebAppProvider::GetForWebApps(profile);
DCHECK(provider);
web_app::ExternalInstallOptions options(
GURL(kMicrosoft365WebAppUrl),
web_app::mojom::UserDisplayMode::kStandalone,
web_app::ExternalInstallSource::kInternalMicrosoft365Setup);
options.fallback_app_name = kMicrosoft365FallbackName;
options.add_to_quick_launch_bar = false;
// Remove the app with the unexpected start URL.
if (auto* app =
provider->registrar_unsafe().LookUpAppByInstallSourceInstallUrl(
web_app::WebAppManagement::Type::kOneDriveIntegration,
GURL(kMicrosoft365WebAppUrl));
app && app->start_url() != kMicrosoft365WebAppUrl) {
LOG(WARNING)
<< "replacing previously installed app with the unexpected URL";
options.force_reinstall = true;
options.uninstall_and_replace = {app->app_id()};
}
// Attempt an online install first.
provider->externally_managed_app_manager().InstallNow(
std::move(options),
base::BindOnce(&OnOfficeWebAppInstalled, profile, std::move(callback)));
}
} // namespace chromeos