0

[Multi Apps] Add crosapi to get all sub-app ids

Adds a function that can be called from ash chrome to retrieve
information about web apps (the ids of the given app's sub apps) stored
in lacros chrome.
Also adds an ash browsertest that connects to the lacros-side
web_app_provider_bridge. To be able to install sub apps on Lacros from
the ash-based test, the change adds a function on the test controller.

Bug: 1354567
Change-Id: Iba5158fec02ddd7d0e01767126a4b540697a4f60
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4249166
Reviewed-by: Christian Flach <cmfcmf@chromium.org>
Commit-Queue: Sam Thiesen <samicolon@google.com>
Cr-Commit-Position: refs/heads/main@{#1107658}
This commit is contained in:
Sam Thiesen
2023-02-21 10:35:35 +00:00
committed by Chromium LUCI CQ
parent 333e2af021
commit 23067a525c
9 changed files with 151 additions and 4 deletions

@ -0,0 +1,79 @@
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/test/bind.h"
#include "base/test/test_future.h"
#include "chrome/browser/ash/crosapi/ash_requires_lacros_browsertestbase.h"
#include "chrome/browser/ash/crosapi/crosapi_manager.h"
#include "chrome/browser/ash/crosapi/web_app_service_ash.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/web_applications/test/app_registry_cache_waiter.h"
#include "chrome/browser/web_applications/web_app_id.h"
#include "chromeos/crosapi/mojom/test_controller.mojom-test-utils.h"
#include "content/public/test/browser_test.h"
namespace crosapi {
namespace {
class WebAppProviderBridgeBrowserTest
: public AshRequiresLacrosBrowserTestBase {
protected:
web_app::AppId InstallWebApp(const std::string& start_url,
apps::WindowMode mode) {
crosapi::mojom::StandaloneBrowserTestControllerAsyncWaiter waiter(
GetStandaloneBrowserTestController());
std::string app_id;
waiter.InstallWebApp(start_url, mode, &app_id);
CHECK(!app_id.empty());
web_app::AppReadinessWaiter(profile(), app_id).Await();
return app_id;
}
web_app::AppId InstallSubApp(const web_app::AppId& parent_app_id,
std::string sub_app_start_url) {
crosapi::mojom::StandaloneBrowserTestControllerAsyncWaiter waiter(
GetStandaloneBrowserTestController());
std::string sub_app_id;
waiter.InstallSubApp(parent_app_id, sub_app_start_url, &sub_app_id);
CHECK(!sub_app_id.empty());
web_app::AppReadinessWaiter(profile(), sub_app_id).Await();
return sub_app_id;
}
Profile* profile() { return browser()->profile(); }
};
IN_PROC_BROWSER_TEST_F(WebAppProviderBridgeBrowserTest, GetSubAppIds) {
if (!HasLacrosArgument()) {
return;
}
web_app::AppId parent_app_id =
InstallWebApp("https://www.parent-app.com", apps::WindowMode::kWindow);
web_app::AppId sub_app_id_1 =
InstallSubApp(parent_app_id, "https://www.parent-app.com/sub-app-1");
web_app::AppId sub_app_id_2 =
InstallSubApp(parent_app_id, "https://www.parent-app.com/sub-app-2");
base::flat_set<web_app::AppId> expected;
expected.emplace(sub_app_id_1);
expected.emplace(sub_app_id_2);
crosapi::mojom::WebAppProviderBridge* web_app_provider_bridge =
crosapi::CrosapiManager::Get()
->crosapi_ash()
->web_app_service_ash()
->GetWebAppProviderBridge();
ASSERT_TRUE(web_app_provider_bridge);
base::test::TestFuture<const std::vector<web_app::AppId>&>
get_sub_apps_future;
web_app_provider_bridge->GetSubAppIds(parent_app_id,
get_sub_apps_future.GetCallback());
base::flat_set<web_app::AppId> results_set{get_sub_apps_future.Get()};
EXPECT_EQ(2u, results_set.size());
EXPECT_EQ(results_set, expected);
}
} // namespace
} // namespace crosapi

@ -173,6 +173,24 @@ void StandaloneBrowserTestController::TtsSpeak(
tts_crosapi_util::SpeakForTesting(std::move(lacros_utterance));
}
void StandaloneBrowserTestController::InstallSubApp(
const web_app::AppId& parent_app_id,
const std::string& sub_app_start_url,
InstallSubAppCallback callback) {
auto info = std::make_unique<WebAppInstallInfo>();
info->start_url = GURL(sub_app_start_url);
info->parent_app_id = parent_app_id;
Profile* profile = ProfileManager::GetPrimaryUserProfile();
auto* provider = web_app::WebAppProvider::GetForWebApps(profile);
provider->scheduler().InstallFromInfo(
std::move(info),
/*overwrite_existing_manifest_fields=*/false,
webapps::WebappInstallSource::SUB_APP,
base::BindOnce(&StandaloneBrowserTestController::WebAppInstallationDone,
weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
}
void StandaloneBrowserTestController::OnUtteranceFinished(int utterance_id) {
// Delete the utterace event delegate object when the utterance is finished.
lacros_utterance_event_delegates_.erase(utterance_id);

@ -42,6 +42,10 @@ class StandaloneBrowserTestController
mojo::PendingRemote<crosapi::mojom::TtsUtteranceClient>
utterance_client) override;
void InstallSubApp(const web_app::AppId& parent_app_id,
const std::string& sub_app_start_url,
InstallSubAppCallback callback) override;
private:
class LacrosUtteranceEventDelegate;

@ -9,6 +9,7 @@
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chromeos/office_web_app/office_web_app.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/web_applications/locks/app_lock.h"
#include "chrome/browser/web_applications/mojom/user_display_mode.mojom.h"
#include "chrome/browser/web_applications/web_app_command_scheduler.h"
#include "chrome/browser/web_applications/web_app_constants.h"
@ -75,6 +76,15 @@ void WebAppProviderBridgeLacros::InstallMicrosoft365(
std::move(callback)));
}
void WebAppProviderBridgeLacros::GetSubAppIds(const web_app::AppId& app_id,
GetSubAppIdsCallback callback) {
g_browser_process->profile_manager()->LoadProfileByPath(
ProfileManager::GetPrimaryUserProfilePath(),
/*incognito=*/false,
base::BindOnce(&WebAppProviderBridgeLacros::GetSubAppIdsImpl, app_id,
std::move(callback)));
}
// static
void WebAppProviderBridgeLacros::WebAppInstalledInArcImpl(
mojom::ArcWebAppInstallInfoPtr arc_install_info,
@ -125,4 +135,22 @@ void WebAppProviderBridgeLacros::InstallMicrosoft365Impl(
chromeos::InstallMicrosoft365(profile, std::move(callback));
}
// static
void WebAppProviderBridgeLacros::GetSubAppIdsImpl(const web_app::AppId& app_id,
GetSubAppIdsCallback callback,
Profile* profile) {
DCHECK(profile);
auto* provider = web_app::WebAppProvider::GetForWebApps(profile);
provider->scheduler().ScheduleCallbackWithLock<web_app::AppLock>(
"WebAppServiceAsh::GetSubApps",
std::make_unique<web_app::AppLockDescription>(app_id),
base::BindOnce(
[](web_app::AppId app_id, web_app::AppLock& lock) {
return lock.registrar().GetAllSubAppIds(app_id);
},
app_id)
.Then(std::move(callback)));
}
} // namespace crosapi

@ -5,6 +5,7 @@
#ifndef CHROME_BROWSER_LACROS_WEB_APP_PROVIDER_BRIDGE_LACROS_H_
#define CHROME_BROWSER_LACROS_WEB_APP_PROVIDER_BRIDGE_LACROS_H_
#include "chrome/browser/web_applications/web_app_id.h"
#include "chromeos/crosapi/mojom/web_app_service.mojom.h"
#include "mojo/public/cpp/bindings/receiver.h"
@ -31,6 +32,8 @@ class WebAppProviderBridgeLacros : public mojom::WebAppProviderBridge {
const std::string& app_id,
GetWebApkCreationParamsCallback callback) override;
void InstallMicrosoft365(InstallMicrosoft365Callback callback) override;
void GetSubAppIds(const web_app::AppId& app_id,
GetSubAppIdsCallback callback) override;
private:
static void WebAppInstalledInArcImpl(
@ -47,6 +50,9 @@ class WebAppProviderBridgeLacros : public mojom::WebAppProviderBridge {
Profile* profile);
static void InstallMicrosoft365Impl(InstallMicrosoft365Callback callback,
Profile* profile);
static void GetSubAppIdsImpl(const web_app::AppId& app_id,
GetSubAppIdsCallback callback,
Profile* profile);
mojo::Receiver<mojom::WebAppProviderBridge> receiver_{this};
};

@ -3755,6 +3755,7 @@ if (!is_android) {
"../browser/ash/child_accounts/parent_access_code/parent_access_service_browsertest.cc",
"../browser/ash/child_accounts/screen_time_controller_browsertest.cc",
"../browser/ash/child_accounts/time_limits/app_time_browsertest.cc",
"../browser/ash/crosapi/web_app_provider_bridge_browsertest.cc",
"../browser/ash/crostini/crostini_browser_test_util.cc",
"../browser/ash/crostini/crostini_browser_test_util.h",
"../browser/ash/crostini/crostini_browsertest.cc",

@ -49,8 +49,8 @@ enum OptionalBoolean {
// Implemented in lacros-chrome.
// Lets the Ash browser tests that require Lacros to send commands to this
// lacros-chrome instance.
// Next version: 4
// Next method id: 4
// Next version: 6
// Next method id: 6
[Stable, Uuid="20e7f031-f4e1-4ad9-bd91-ad59eb8b1504"]
interface StandaloneBrowserTestController {
// Installs a test web app in lacros-chrome given a start URL and mode (open
@ -75,6 +75,12 @@ interface StandaloneBrowserTestController {
[MinVersion=4]
TtsSpeak@4(TtsUtterance utterance,
pending_remote<TtsUtteranceClient> utterance_client);
// Installs an app with the given start url as a sub app of the given parent
// app in Lacros.
[MinVersion=5]
InstallSubApp@5(string parent_app_id, string sub_app_start_url)
=> (string sub_app_id);
};
// Allows callers running in lacros to trigger test events that are passed to

@ -29,8 +29,8 @@ struct WebApkCreationParams {
// Implemented in lacros-chrome. Allows ash-chrome to modify web app state in
// lacros-chrome.
// Next version: 3
// Next method id: 4
// Next version: 4
// Next method id: 5
[Stable, Uuid="84eb46eb-76fe-439c-9fcb-3388492e141d"]
interface WebAppProviderBridge {
// Called when a web app described by |info| is installed in ARC (Android
@ -56,6 +56,10 @@ interface WebAppProviderBridge {
// Installs Microsoft 365 web app in Lacros.
[MinVersion=2]
InstallMicrosoft365@3() => (WebAppInstallResultCode install_result);
// Returns the ids of all the sub-apps of the given app.
[MinVersion=3]
GetSubAppIds@4(string app_id) => (array<string> sub_apps);
};
// An interface implemented in ash-chrome. Allows lacros-chrome:

@ -15,6 +15,7 @@ SelectToSpeak*
SwitchAccess*
VpnExtensionObserverBrowserTest*
WebAppsCrosapiBrowserTest*
WebAppProviderBridgeBrowserTest*
WebKioskAshRequiresLacrosTest*
# TODO(b/262789941) Enable more accessibility tests.
-ChromeVoxBackgroundTest.TabSwitchAndRefreshRecovery