Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 16 additions & 10 deletions shell/platform/windows/uwptool_main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ namespace {
void PrintInstalledApps() {
flutter::ApplicationStore app_store;
for (const flutter::Application& app : app_store.GetInstalledApplications()) {
std::wcout << app.GetPackageId() << std::endl;
std::wcout << app.GetPackageFamily() << std::endl;
}
}

Expand All @@ -31,9 +31,15 @@ void PrintInstalledApps() {
// Returns -1 if no matching app, or multiple matching apps are found, or if
// the app fails to launch. Otherwise, the process ID of the launched app is
// returned.
int LaunchApp(const std::wstring_view app_id, const std::wstring_view args) {
flutter::Application app(app_id);
return app.Launch(args);
int LaunchApp(const std::wstring_view package_family,
const std::wstring_view args) {
flutter::ApplicationStore app_store;
std::optional<flutter::Application> app =
app_store.GetInstalledApplication(package_family);
if (!app) {
return -1;
}
return app->Launch(args);
}

// Prints the command usage to stderr.
Expand Down Expand Up @@ -66,8 +72,8 @@ int main(int argc, char** argv) {
return 1;
}

// Get the package ID.
std::string package_id = args[1];
// Get the package family.
std::string package_family = args[1];

// Concatenate the remaining args, comma-separated.
std::ostringstream app_args;
Expand All @@ -77,16 +83,16 @@ int main(int argc, char** argv) {
app_args << ",";
}
}
int process_id = LaunchApp(flutter::Utf16FromUtf8(package_id),
int process_id = LaunchApp(flutter::Utf16FromUtf8(package_family),
flutter::Utf16FromUtf8(app_args.str()));
if (process_id == -1) {
std::cerr << "error: Failed to launch app with package ID " << package_id
<< std::endl;
std::cerr << "error: Failed to launch app with package family "
<< package_family << std::endl;
return 1;
}

// Write an informative message for the user to stderr.
std::cerr << "Launched app with package ID " << package_id
std::cerr << "Launched app with package family " << package_family
<< ". PID: " << std::endl;
// Write the PID to stdout. The flutter tool reads this value in.
std::cout << process_id << std::endl;
Expand Down
32 changes: 25 additions & 7 deletions shell/platform/windows/uwptool_utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,16 @@
#include <winrt/Windows.Management.Deployment.h>
#include <winrt/base.h>

#include <optional>
#include <string>
#include <unordered_set>
#include <vector>

namespace flutter {

Application::Application(const std::wstring_view package_id)
: package_id_(package_id) {}
Application::Application(const std::wstring_view package_family,
const std::wstring_view package_full_name)
: package_family_(package_family), package_full_name_(package_full_name) {}

int Application::Launch(const std::wstring_view args) {
// Create the ApplicationActivationManager.
Expand All @@ -34,7 +36,7 @@ int Application::Launch(const std::wstring_view args) {
// Launch the application.
DWORD process_id;
ACTIVATEOPTIONS options = AO_NONE;
std::wstring app_user_model_id = package_id_ + L"!App";
std::wstring app_user_model_id = package_family_ + L"!App";
hresult = activation_manager->ActivateApplication(
app_user_model_id.data(), args.data(), options, &process_id);
if (FAILED(hresult)) {
Expand All @@ -43,18 +45,34 @@ int Application::Launch(const std::wstring_view args) {
return process_id;
}

std::vector<Application> ApplicationStore::GetInstalledApplications() {
std::vector<Application> ApplicationStore::GetInstalledApplications() const {
using winrt::Windows::ApplicationModel::Package;
using winrt::Windows::Management::Deployment::PackageManager;

// Find packages for the current user (default for empty string).
PackageManager package_manager;
std::unordered_set<std::wstring> package_ids;
std::vector<Application> apps;
for (const Package& package : package_manager.FindPackagesForUser(L"")) {
package_ids.emplace(package.Id().FamilyName().c_str());
apps.emplace_back(package.Id().FamilyName().c_str(),
package.Id().FullName().c_str());
}
std::vector<Application> apps(package_ids.begin(), package_ids.end());
return apps;
}

std::optional<Application> ApplicationStore::GetInstalledApplication(
const std::wstring_view package_family) const {
using winrt::Windows::ApplicationModel::Package;
using winrt::Windows::Management::Deployment::PackageManager;

// Find packages for the current user (default for empty string).
PackageManager package_manager;
std::vector<Application> apps;
for (const Package& package :
package_manager.FindPackagesForUser(L"", package_family)) {
return std::optional(Application(package.Id().FamilyName().c_str(),
package.Id().FullName().c_str()));
}
return std::nullopt;
}

} // namespace flutter
20 changes: 15 additions & 5 deletions shell/platform/windows/uwptool_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#ifndef FLUTTER_SHELL_PLATFORM_WINDOWS_UWPTOOL_UTILS_H_
#define FLUTTER_SHELL_PLATFORM_WINDOWS_UWPTOOL_UTILS_H_

#include <optional>
#include <string>
#include <vector>

Expand All @@ -13,20 +14,25 @@ namespace flutter {
// A UWP application.
class Application {
public:
explicit Application(const std::wstring_view package_id);
explicit Application(const std::wstring_view package_family,
const std::wstring_view package_full_name);
Application(const Application& other) = default;
Application& operator=(const Application& other) = default;

// Returns the package ID.
std::wstring GetPackageId() const { return package_id_; }
// Returns the package family.
std::wstring GetPackageFamily() const { return package_family_; }

// Returns the package full name.
std::wstring GetPackageFullName() const { return package_full_name_; }

// Launches the application with the specified list of launch arguments.
//
// Returns the process ID on success, or -1 on failure.
int Launch(const std::wstring_view args);

private:
std::wstring package_id_;
std::wstring package_family_;
std::wstring package_full_name_;
};

// The machine-local store of installed applications.
Expand All @@ -39,7 +45,11 @@ class ApplicationStore {
ApplicationStore& operator=(const ApplicationStore& other) = delete;

// Returns a list of all installed application user model IDs.
std::vector<Application> GetInstalledApplications();
std::vector<Application> GetInstalledApplications() const;

// Returns a list of all installed application user model IDs.
std::optional<Application> GetInstalledApplication(
const std::wstring_view package_family) const;
};

} // namespace flutter
Expand Down
15 changes: 14 additions & 1 deletion shell/platform/windows/uwptool_utils_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,23 @@ TEST(ApplicationStore, GetInstalledApplications) {
EXPECT_FALSE(apps.empty());

auto ms_pos = std::find_if(apps.begin(), apps.end(), [](const auto& app) {
return app.GetPackageId().rfind(L"Microsoft.", 0);
return app.GetPackageFamily().rfind(L"Microsoft.", 0);
});
EXPECT_TRUE(ms_pos != apps.end());
}

// Verify that we can look up an app by family name.
TEST(ApplicationStore, GetInstalledApplication) {
ApplicationStore app_store;
std::vector<Application> apps = app_store.GetInstalledApplications();
EXPECT_FALSE(apps.empty());

std::optional<Application> found_app =
app_store.GetInstalledApplication(apps[0].GetPackageFamily());
ASSERT_TRUE(found_app != std::nullopt);
EXPECT_EQ(found_app->GetPackageFamily(), apps[0].GetPackageFamily());
EXPECT_EQ(found_app->GetPackageFullName(), apps[0].GetPackageFullName());
}

} // namespace testing
} // namespace flutter