1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef CHROME_BROWSER_CHROMEOS_CROSTINI_CROSTINI_UTIL_H_
6 #define CHROME_BROWSER_CHROMEOS_CROSTINI_CROSTINI_UTIL_H_
7 
8 #include <string>
9 #include <utility>
10 #include <vector>
11 
12 #include "base/callback.h"
13 #include "base/callback_helpers.h"
14 #include "base/files/file_path.h"
15 #include "base/optional.h"
16 #include "base/values.h"
17 #include "chrome/browser/chromeos/crostini/crostini_simple_types.h"
18 #include "storage/browser/file_system/file_system_url.h"
19 #include "third_party/abseil-cpp/absl/types/variant.h"
20 
21 namespace base {
22 class FilePath;
23 }  // namespace base
24 
25 namespace views {
26 class Widget;
27 }  // namespace views
28 
29 class Profile;
30 
31 namespace crostini {
32 
33 // TODO(crbug.com/1092657): kCrostiniDeletedTerminalId can be removed after M86.
34 // We use an arbitrary well-formed extension id for the Terminal app, this
35 // is equal to GenerateId("Terminal").
36 extern const char kCrostiniDeletedTerminalId[];
37 // web_app::GenerateAppIdFromURL(
38 //     GURL("chrome-untrusted://terminal/html/terminal.html"))
39 extern const char kCrostiniTerminalSystemAppId[];
40 
41 extern const char kCrostiniDefaultVmName[];
42 extern const char kCrostiniDefaultContainerName[];
43 extern const char kCrostiniDefaultUsername[];
44 // In order to be compatible with sync folder id must match standard.
45 // Generated using crx_file::id_util::GenerateId("LinuxAppsFolder")
46 extern const char kCrostiniFolderId[];
47 extern const char kCrostiniDefaultImageServerUrl[];
48 extern const char kCrostiniStretchImageAlias[];
49 extern const char kCrostiniBusterImageAlias[];
50 extern const char kCrostiniDlcName[];
51 
52 extern const base::FilePath::CharType kHomeDirectory[];
53 
54 struct LinuxPackageInfo;
55 
56 // A unique identifier for our containers.
57 struct ContainerId {
58   ContainerId(std::string vm_name, std::string container_name) noexcept;
59 
60   static ContainerId GetDefault();
61 
62   std::string vm_name;
63   std::string container_name;
64 };
65 
66 bool operator<(const ContainerId& lhs, const ContainerId& rhs) noexcept;
67 bool operator==(const ContainerId& lhs, const ContainerId& rhs) noexcept;
68 inline bool operator!=(const ContainerId& lhs,
69                        const ContainerId& rhs) noexcept {
70   return !(lhs == rhs);
71 }
72 
73 std::ostream& operator<<(std::ostream& ostream,
74                          const ContainerId& container_id);
75 
76 // Checks if user profile is able to a crostini app with a given app_id.
77 bool IsUninstallable(Profile* profile, const std::string& app_id);
78 
79 // Returns whether the default Crostini VM is running for the user.
80 bool IsCrostiniRunning(Profile* profile);
81 
82 // Whether the user is able to perform a container upgrade.
83 bool ShouldAllowContainerUpgrade(Profile* profile);
84 
85 // Returns whether default Crostini container should be configured according to
86 // the configuration specified by CrostiniAnsiblePlaybook user policy.
87 bool ShouldConfigureDefaultContainer(Profile* profile);
88 
89 // Returns whether a dialog from Crostini is blocking the immediate launch.
90 bool MaybeShowCrostiniDialogBeforeLaunch(Profile* profile,
91                                          CrostiniResult result);
92 
93 using LaunchArg = absl::variant<storage::FileSystemURL, std::string>;
94 
95 // Launch a Crostini App with a given set of files, given as absolute paths in
96 // the container. For apps which can only be launched with a single file,
97 // launch multiple instances.
98 void LaunchCrostiniApp(Profile* profile,
99                        const std::string& app_id,
100                        int64_t display_id,
101                        const std::vector<LaunchArg>& args = {},
102                        CrostiniSuccessCallback callback = base::DoNothing());
103 
104 // Retrieves cryptohome_id from profile.
105 std::string CryptohomeIdForProfile(Profile* profile);
106 
107 // Retrieves username from profile.
108 std::string DefaultContainerUserNameForProfile(Profile* profile);
109 
110 // Returns the mount directory within the container where paths from the Chrome
111 // OS host such as within Downloads are shared with the container.
112 base::FilePath ContainerChromeOSBaseDirectory();
113 
114 // The Terminal opens Crosh but overrides the Browser's app_name so that we can
115 // identify it as the Crostini Terminal. In the future, we will also use these
116 // for Crostini apps marked Terminal=true in their .desktop file.
117 std::string AppNameFromCrostiniAppId(const std::string& id);
118 
119 // Returns nullopt for a non-Crostini app name.
120 base::Optional<std::string> CrostiniAppIdFromAppName(
121     const std::string& app_name);
122 
123 // Returns a list of ports currently being forwarded in Crostini as a JSON
124 // object.
125 std::string GetActivePortListAsJSON(Profile* profile);
126 
127 // These values are persisted to logs. Entries should not be renumbered and
128 // numeric values should never be reused.
129 enum class CrostiniUISurface { kSettings = 0, kAppList = 1, kCount };
130 
131 // See chrome/browser/ui/views/crostini for implementation of the ShowXXX
132 // functions below.
133 
134 // Shows the Crostini Uninstaller dialog.
135 void ShowCrostiniUninstallerView(Profile* profile,
136                                  CrostiniUISurface ui_surface);
137 bool IsCrostiniRecoveryViewShowing();
138 
139 // Shows the Crostini App installer dialog.
140 void ShowCrostiniAppInstallerView(Profile* profile,
141                                   const LinuxPackageInfo& package_info);
142 // Shows the Crostini force-close dialog. If |app_name| is nonempty, the dialog
143 // will include the window's name as text. Returns a handle to that dialog, so
144 // that we can add observers to the dialog itself.
145 views::Widget* ShowCrostiniForceCloseDialog(
146     const std::string& app_name,
147     views::Widget* closable_widget,
148     base::OnceClosure force_close_callback);
149 // Shows the Crostini Termina Upgrade dialog (for blocking crostini start until
150 // Termina version matches).
151 void ShowCrostiniUpdateComponentView(Profile* profile,
152                                      CrostiniUISurface ui_surface);
153 // Shows the ui with the error message when installing a package fails.
154 void ShowCrostiniPackageInstallFailureView(const std::string& error_message);
155 
156 // Shows the Crostini Container Upgrade dialog (for running upgrades in the
157 // container).
158 void ShowCrostiniUpdateFilesystemView(Profile* profile,
159                                       CrostiniUISurface ui_surface);
160 // Show the Crostini Container Upgrade dialog after a delay
161 // (CloseCrostiniUpdateFilesystemView will cancel the next dialog show).
162 void PrepareShowCrostiniUpdateFilesystemView(Profile* profile,
163                                              CrostiniUISurface ui_surface);
164 // Closes the current CrostiniUpdateFilesystemView or ensures that the view will
165 // not open until PrepareShowCrostiniUpdateFilesystemView is called again.
166 void CloseCrostiniUpdateFilesystemView();
167 
168 // Show the Crostini Software Config dialog (for installing Ansible and
169 // applying an Ansible playbook in the container).
170 void ShowCrostiniAnsibleSoftwareConfigView(Profile* profile);
171 
172 // Show the Crostini Recovery dialog when Crostini is still running after a
173 // Chrome crash. The user must either restart the VM, or launch a terminal.
174 void ShowCrostiniRecoveryView(Profile* profile,
175                               CrostiniUISurface ui_surface,
176                               const std::string& app_id,
177                               int64_t display_id,
178                               const std::vector<LaunchArg>& args,
179                               CrostiniSuccessCallback callback);
180 
181 // Add a newly created LXD container to the kCrostiniContainers pref
182 void AddNewLxdContainerToPrefs(Profile* profile,
183                                const ContainerId& container_id);
184 
185 // Remove a newly deleted LXD container from the kCrostiniContainers pref, and
186 // deregister its apps and mime types.
187 void RemoveLxdContainerFromPrefs(Profile* profile,
188                                  const ContainerId& container_id);
189 
190 // Returns a string to be displayed in a notification with the estimated time
191 // left for an operation to run which started and time |start| and is current
192 // at |percent| way through.
193 base::string16 GetTimeRemainingMessage(base::TimeTicks start, int percent);
194 
195 // Returns a pref value stored for a specific container.
196 const base::Value* GetContainerPrefValue(Profile* profile,
197                                          const ContainerId& container_id,
198                                          const std::string& key);
199 
200 // Sets a pref value for a specific container.
201 void UpdateContainerPref(Profile* profile,
202                          const ContainerId& container_id,
203                          const std::string& key,
204                          base::Value value);
205 
206 const ContainerId& DefaultContainerId();
207 
208 }  // namespace crostini
209 
210 #endif  // CHROME_BROWSER_CHROMEOS_CROSTINI_CROSTINI_UTIL_H_
211