Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit cb3ee34

Browse files
authored
[uwptool] Move Launch, Uninstall to AppStore class (#26315)
This refactoring moves the Application Launch and Uninstall methods to the ApplicationStore class. This simplifies writing tests for Command classes since the Application class is now a plain old data class, and ApplicationStore can be replaced with a fake implementation for hermetic testing, while I'll do in a follow-up patch. Bug: flutter/flutter#83072
1 parent 2f067fc commit cb3ee34

File tree

4 files changed

+102
-103
lines changed

4 files changed

+102
-103
lines changed

shell/platform/windows/uwptool_commands.cc

Lines changed: 8 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ int InstallCommand::Run(const std::vector<std::string>& args) const {
3131
dependency_uris.push_back(flutter::Utf16FromUtf8(args[i]));
3232
}
3333
flutter::ApplicationStore app_store;
34-
if (app_store.InstallApp(package_uri, dependency_uris)) {
34+
if (app_store.Install(package_uri, dependency_uris)) {
3535
std::wcerr << L"Installed application " << package_uri << std::endl;
3636
return 0;
3737
}
@@ -44,20 +44,9 @@ bool UninstallCommand::ValidateArgs(
4444
}
4545

4646
int UninstallCommand::Run(const std::vector<std::string>& args) const {
47-
std::wstring package_family = flutter::Utf16FromUtf8(args[0]);
48-
bool success = true;
4947
flutter::ApplicationStore app_store;
50-
for (flutter::Application& app : app_store.GetApps(package_family)) {
51-
if (app.Uninstall()) {
52-
std::wcerr << L"Uninstalled application " << app.GetPackageFullName()
53-
<< std::endl;
54-
} else {
55-
std::wcerr << L"error: Failed to uninstall application "
56-
<< app.GetPackageFullName() << std::endl;
57-
success = false;
58-
}
59-
}
60-
return success ? 0 : 1;
48+
std::wstring package_family = flutter::Utf16FromUtf8(args[0]);
49+
return app_store.Uninstall(package_family) ? 0 : 1;
6150
}
6251

6352
bool LaunchCommand::ValidateArgs(const std::vector<std::string>& args) const {
@@ -76,11 +65,13 @@ int LaunchCommand::Run(const std::vector<std::string>& args) const {
7665
app_args << ",";
7766
}
7867
}
79-
int process_id = LaunchApp(flutter::Utf16FromUtf8(package_family),
80-
flutter::Utf16FromUtf8(app_args.str()));
68+
flutter::ApplicationStore app_store;
69+
int process_id = app_store.Launch(flutter::Utf16FromUtf8(package_family),
70+
flutter::Utf16FromUtf8(app_args.str()));
8171
if (process_id == -1) {
8272
std::cerr << "error: Failed to launch app with package family "
83-
<< package_family << std::endl;
73+
<< package_family << " arguments [" << app_args.str() << "]"
74+
<< std::endl;
8475
return 1;
8576
}
8677

@@ -92,21 +83,4 @@ int LaunchCommand::Run(const std::vector<std::string>& args) const {
9283
return 0;
9384
}
9485

95-
// Launches the app installed on the system with the specified package.
96-
//
97-
// Returns -1 if no matching app, or multiple matching apps are found, or if
98-
// the app fails to launch. Otherwise, the process ID of the launched app is
99-
// returned.
100-
int LaunchCommand::LaunchApp(const std::wstring_view package_family,
101-
const std::wstring_view args) const {
102-
flutter::ApplicationStore app_store;
103-
for (flutter::Application& app : app_store.GetApps(package_family)) {
104-
int process_id = app.Launch(args);
105-
if (process_id != -1) {
106-
return process_id;
107-
}
108-
}
109-
return -1;
110-
}
111-
11286
} // namespace flutter

shell/platform/windows/uwptool_commands.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,11 @@ class UninstallCommand : public Command {
7373
int Run(const std::vector<std::string>& args) const override;
7474
};
7575

76-
// Command that launches the specified application package.
76+
// Launches the app installed on the system with the specified package.
77+
//
78+
// Returns -1 if no matching app, or multiple matching apps are found, or if
79+
// the app fails to launch. Otherwise, the process ID of the launched app is
80+
// returned.
7781
class LaunchCommand : public Command {
7882
public:
7983
LaunchCommand()

shell/platform/windows/uwptool_utils.cc

Lines changed: 63 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -20,58 +20,6 @@
2020

2121
namespace flutter {
2222

23-
Application::Application(const std::wstring_view package_name,
24-
const std::wstring_view package_family,
25-
const std::wstring_view package_full_name)
26-
: package_name_(package_name),
27-
package_family_(package_family),
28-
package_full_name_(package_full_name) {}
29-
30-
int Application::Launch(const std::wstring_view args) {
31-
// Create the ApplicationActivationManager.
32-
winrt::com_ptr<IApplicationActivationManager> activation_manager;
33-
HRESULT hresult = ::CoCreateInstance(
34-
CLSID_ApplicationActivationManager, nullptr, CLSCTX_INPROC_SERVER,
35-
IID_IApplicationActivationManager, activation_manager.put_void());
36-
if (FAILED(hresult)) {
37-
return -1;
38-
}
39-
40-
// Launch the application.
41-
DWORD process_id;
42-
ACTIVATEOPTIONS options = AO_NONE;
43-
std::wstring app_user_model_id = package_family_ + L"!App";
44-
hresult = activation_manager->ActivateApplication(
45-
app_user_model_id.data(), args.data(), options, &process_id);
46-
if (FAILED(hresult)) {
47-
return -1;
48-
}
49-
return process_id;
50-
}
51-
52-
bool Application::Uninstall() {
53-
using winrt::Windows::Foundation::AsyncStatus;
54-
using winrt::Windows::Management::Deployment::PackageManager;
55-
using winrt::Windows::Management::Deployment::RemovalOptions;
56-
57-
PackageManager package_manager;
58-
auto operation = package_manager.RemovePackageAsync(
59-
package_full_name_, RemovalOptions::RemoveForAllUsers);
60-
operation.get();
61-
62-
if (operation.Status() == AsyncStatus::Completed) {
63-
return true;
64-
} else if (operation.Status() == AsyncStatus::Canceled) {
65-
return false;
66-
} else if (operation.Status() == AsyncStatus::Error) {
67-
auto result = operation.GetResults();
68-
std::wcerr << L"error: uninstall failed for package " << package_full_name_
69-
<< L" with error: " << result.ErrorText().c_str() << std::endl;
70-
return false;
71-
}
72-
return false;
73-
}
74-
7523
std::vector<Application> ApplicationStore::GetApps() const {
7624
using winrt::Windows::ApplicationModel::Package;
7725
using winrt::Windows::Management::Deployment::PackageManager;
@@ -112,7 +60,7 @@ std::vector<Application> ApplicationStore::GetApps(
11260
return apps;
11361
}
11462

115-
bool ApplicationStore::InstallApp(
63+
bool ApplicationStore::Install(
11664
const std::wstring_view package_uri,
11765
const std::vector<std::wstring>& dependency_uris) {
11866
using winrt::Windows::Foundation::AsyncStatus;
@@ -145,4 +93,66 @@ bool ApplicationStore::InstallApp(
14593
return false;
14694
}
14795

96+
bool ApplicationStore::Uninstall(const std::wstring_view package_family) {
97+
bool success = true;
98+
for (const Application& app : GetApps(package_family)) {
99+
if (Uninstall(app.GetPackageFullName())) {
100+
std::wcerr << L"Uninstalled application " << app.GetPackageFullName()
101+
<< std::endl;
102+
} else {
103+
std::wcerr << L"error: Failed to uninstall application "
104+
<< app.GetPackageFullName() << std::endl;
105+
success = false;
106+
}
107+
}
108+
return success;
109+
}
110+
111+
bool ApplicationStore::UninstallPackage(
112+
const std::wstring_view package_full_name) {
113+
using winrt::Windows::Foundation::AsyncStatus;
114+
using winrt::Windows::Management::Deployment::PackageManager;
115+
using winrt::Windows::Management::Deployment::RemovalOptions;
116+
117+
PackageManager package_manager;
118+
auto operation = package_manager.RemovePackageAsync(
119+
package_full_name, RemovalOptions::RemoveForAllUsers);
120+
operation.get();
121+
122+
if (operation.Status() == AsyncStatus::Completed) {
123+
return true;
124+
} else if (operation.Status() == AsyncStatus::Canceled) {
125+
return false;
126+
} else if (operation.Status() == AsyncStatus::Error) {
127+
auto result = operation.GetResults();
128+
std::wcerr << L"error: uninstall failed for package " << package_full_name
129+
<< L" with error: " << result.ErrorText().c_str() << std::endl;
130+
return false;
131+
}
132+
return false;
133+
}
134+
135+
int ApplicationStore::Launch(const std::wstring_view package_family,
136+
const std::wstring_view args) {
137+
// Create the ApplicationActivationManager.
138+
winrt::com_ptr<IApplicationActivationManager> activation_manager;
139+
HRESULT hresult = ::CoCreateInstance(
140+
CLSID_ApplicationActivationManager, nullptr, CLSCTX_INPROC_SERVER,
141+
IID_IApplicationActivationManager, activation_manager.put_void());
142+
if (FAILED(hresult)) {
143+
return -1;
144+
}
145+
146+
// Launch the application.
147+
DWORD process_id;
148+
ACTIVATEOPTIONS options = AO_NONE;
149+
std::wstring app_user_model_id = std::wstring(package_family) + L"!App";
150+
hresult = activation_manager->ActivateApplication(
151+
app_user_model_id.data(), args.data(), options, &process_id);
152+
if (FAILED(hresult)) {
153+
return -1;
154+
}
155+
return process_id;
156+
}
157+
148158
} // namespace flutter

shell/platform/windows/uwptool_utils.h

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,13 @@ namespace flutter {
1414
// A UWP application.
1515
class Application {
1616
public:
17-
explicit Application(const std::wstring_view package_name,
18-
const std::wstring_view package_family,
19-
const std::wstring_view package_full_name);
17+
Application(const std::wstring_view package_name,
18+
const std::wstring_view package_family,
19+
const std::wstring_view package_full_name)
20+
: package_name_(package_name),
21+
package_family_(package_family),
22+
package_full_name_(package_full_name) {}
23+
2024
Application(const Application& other) = default;
2125
Application& operator=(const Application& other) = default;
2226

@@ -39,16 +43,6 @@ class Application {
3943
// package name, publisher, architecture and version information.
4044
std::wstring GetPackageFullName() const { return package_full_name_; }
4145

42-
// Launches the application with the specified list of launch arguments.
43-
//
44-
// Returns the process ID on success, or -1 on failure.
45-
int Launch(const std::wstring_view args);
46-
47-
// Uninstalls the application.
48-
//
49-
// Returns true on success.
50-
bool Uninstall();
51-
5246
private:
5347
std::wstring package_name_;
5448
std::wstring package_family_;
@@ -75,8 +69,25 @@ class ApplicationStore {
7569
//
7670
// Installs the application located at package_uri with the specified
7771
// dependencies.
78-
bool InstallApp(const std::wstring_view package_uri,
79-
const std::vector<std::wstring>& dependency_uris);
72+
bool Install(const std::wstring_view package_uri,
73+
const std::vector<std::wstring>& dependency_uris);
74+
75+
// Uninstalls all application packages in the specified package family.
76+
//
77+
// Returns true on success.
78+
bool Uninstall(const std::wstring_view package_family);
79+
80+
// Launches the application with the specified list of launch arguments.
81+
//
82+
// Returns the process ID on success, or -1 on failure.
83+
int Launch(const std::wstring_view package_family,
84+
const std::wstring_view args);
85+
86+
private:
87+
// Uninstalls the specified application package.
88+
//
89+
// Returns true on success.
90+
bool UninstallPackage(const std::wstring_view package_full_name);
8091
};
8192

8293
} // namespace flutter

0 commit comments

Comments
 (0)