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