1 // Copyright (c) 2012 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_UI_WEBUI_NTP_APP_LAUNCHER_HANDLER_H_ 6 #define CHROME_BROWSER_UI_WEBUI_NTP_APP_LAUNCHER_HANDLER_H_ 7 8 #include <memory> 9 #include <set> 10 #include <string> 11 12 #include "base/macros.h" 13 #include "base/optional.h" 14 #include "base/scoped_observer.h" 15 #include "base/task/cancelable_task_tracker.h" 16 #include "chrome/browser/extensions/extension_uninstall_dialog.h" 17 #include "chrome/browser/ui/extensions/extension_enable_flow_delegate.h" 18 #include "chrome/browser/web_applications/components/app_registrar.h" 19 #include "chrome/browser/web_applications/components/app_registrar_observer.h" 20 #include "chrome/browser/web_applications/components/os_integration_manager.h" 21 #include "chrome/browser/web_applications/components/web_app_id.h" 22 #include "chrome/common/extensions/extension_constants.h" 23 #include "components/favicon/core/favicon_service.h" 24 #include "components/prefs/pref_change_registrar.h" 25 #include "components/sync/model/string_ordinal.h" 26 #include "content/public/browser/notification_observer.h" 27 #include "content/public/browser/notification_registrar.h" 28 #include "content/public/browser/web_ui_message_handler.h" 29 #include "extensions/browser/extension_registry_observer.h" 30 #include "extensions/common/extension.h" 31 32 class ExtensionEnableFlow; 33 class PrefChangeRegistrar; 34 class Profile; 35 36 namespace extensions { 37 class ExtensionService; 38 } // namespace extensions 39 40 namespace favicon_base { 41 struct FaviconImageResult; 42 } 43 44 namespace user_prefs { 45 class PrefRegistrySyncable; 46 } 47 48 namespace web_app { 49 class WebAppProvider; 50 } // namespace web_app 51 52 // The handler for Javascript messages related to the "apps" view. 53 class AppLauncherHandler 54 : public content::WebUIMessageHandler, 55 public extensions::ExtensionUninstallDialog::Delegate, 56 public ExtensionEnableFlowDelegate, 57 public content::NotificationObserver, 58 public web_app::AppRegistrarObserver, 59 public extensions::ExtensionRegistryObserver { 60 public: 61 AppLauncherHandler(extensions::ExtensionService* extension_service, 62 web_app::WebAppProvider* web_app_provider); 63 ~AppLauncherHandler() override; 64 65 void CreateWebAppInfo(const web_app::AppId& app_id, 66 base::DictionaryValue* value); 67 68 void CreateExtensionInfo(const extensions::Extension* extension, 69 base::DictionaryValue* value); 70 71 // Registers values (strings etc.) for the page. 72 static void GetLocalizedValues(Profile* profile, 73 base::DictionaryValue* values); 74 75 // Register per-profile preferences. 76 static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry); 77 78 // WebUIMessageHandler: 79 void RegisterMessages() override; 80 81 // content::NotificationObserver: 82 void Observe(int type, 83 const content::NotificationSource& source, 84 const content::NotificationDetails& details) override; 85 86 // extensions::ExtensionRegistryObserver: 87 void OnExtensionLoaded(content::BrowserContext* browser_context, 88 const extensions::Extension* extension) override; 89 void OnExtensionUnloaded(content::BrowserContext* browser_context, 90 const extensions::Extension* extension, 91 extensions::UnloadedExtensionReason reason) override; 92 void OnExtensionUninstalled(content::BrowserContext* browser_context, 93 const extensions::Extension* extension, 94 extensions::UninstallReason reason) override; 95 96 // web_app::AppRegistrarObserver: 97 void OnWebAppInstalled(const web_app::AppId& app_id) override; 98 void OnWebAppUninstalled(const web_app::AppId& app_id) override; 99 void OnAppRegistrarDestroyed() override; 100 101 // Populate the given dictionary with all installed app info. 102 void FillAppDictionary(base::DictionaryValue* value); 103 104 // Create a dictionary value for the given extension. 105 std::unique_ptr<base::DictionaryValue> GetExtensionInfo( 106 const extensions::Extension* extension); 107 108 // Create a dictionary value for the given web app. 109 std::unique_ptr<base::DictionaryValue> GetWebAppInfo( 110 const web_app::AppId& app_id); 111 112 // Populate the given dictionary with the web store promo content. 113 void FillPromoDictionary(base::DictionaryValue* value); 114 115 // Handles the "launchApp" message with unused |args|. 116 void HandleGetApps(const base::ListValue* args); 117 118 // Handles the "launchApp" message with |args| containing [extension_id, 119 // source] with optional [url, disposition], |disposition| defaulting to 120 // CURRENT_TAB. 121 void HandleLaunchApp(const base::ListValue* args); 122 123 // Handles the "setLaunchType" message with args containing [extension_id, 124 // launch_type]. 125 void HandleSetLaunchType(const base::ListValue* args); 126 127 // Handles the "uninstallApp" message with |args| containing [extension_id] 128 // and an optional bool to not confirm the uninstall when true, defaults to 129 // false. 130 void HandleUninstallApp(const base::ListValue* args); 131 132 // Handles the "createAppShortcut" message with |args| containing 133 // [extension_id]. 134 void HandleCreateAppShortcut(const base::ListValue* args); 135 136 // Handles the "installAppLocally" message with |args| containing 137 // [extension_id]. 138 void HandleInstallAppLocally(const base::ListValue* args); 139 140 // Handles the "showAppInfo" message with |args| containing [extension_id]. 141 void HandleShowAppInfo(const base::ListValue* args); 142 143 // Handles the "reorderApps" message with |args| containing [dragged_app_id, 144 // app_order]. 145 void HandleReorderApps(const base::ListValue* args); 146 147 // Handles the "setPageIndex" message with |args| containing [extension_id, 148 // page_index]. 149 void HandleSetPageIndex(const base::ListValue* args); 150 151 // Handles "saveAppPageName" message with |args| containing [name, 152 // page_index]. 153 void HandleSaveAppPageName(const base::ListValue* args); 154 155 // Handles "generateAppForLink" message with |args| containing [url, title, 156 // page_index]. 157 void HandleGenerateAppForLink(const base::ListValue* args); 158 159 // Handles "pageSelected" message with |args| containing [page_index]. 160 void HandlePageSelected(const base::ListValue* args); 161 162 // Handles "runOnOsLogin" message with |args| containing [app_id, mode] 163 void HandleRunOnOsLogin(const base::ListValue* args); 164 165 private: 166 struct AppInstallInfo { 167 AppInstallInfo(); 168 ~AppInstallInfo(); 169 170 base::string16 title; 171 GURL app_url; 172 syncer::StringOrdinal page_ordinal; 173 }; 174 175 // Reset some instance flags we use to track the currently uninstalling app. 176 void CleanupAfterUninstall(); 177 178 // Prompts the user to re-enable the app for |extension_id|. 179 void PromptToEnableApp(const std::string& extension_id); 180 181 // Records result to UMA after OS Hooks are installed. 182 void OnOsHooksInstalled(const web_app::AppId& app_id, 183 const web_app::OsHooksResults os_hooks_results); 184 185 // ExtensionUninstallDialog::Delegate: 186 void OnExtensionUninstallDialogClosed(bool did_start_uninstall, 187 const base::string16& error) override; 188 189 // ExtensionEnableFlowDelegate: 190 void ExtensionEnableFlowFinished() override; 191 void ExtensionEnableFlowAborted(bool user_initiated) override; 192 193 // Returns the ExtensionUninstallDialog object for this class, creating it if 194 // needed. 195 extensions::ExtensionUninstallDialog* CreateExtensionUninstallDialog(); 196 197 // Continuation for installing a bookmark app after favicon lookup. 198 void OnFaviconForAppInstallFromLink( 199 std::unique_ptr<AppInstallInfo> install_info, 200 const favicon_base::FaviconImageResult& image_result); 201 202 // Sends |highlight_app_id_| to the js. 203 void SetAppToBeHighlighted(); 204 205 void OnExtensionPreferenceChanged(); 206 207 // Called when an extension is removed (unloaded or uninstalled). Updates the 208 // UI. 209 void ExtensionRemoved(const extensions::Extension* extension, 210 bool is_uninstall); 211 212 // True if the extension should be displayed. 213 bool ShouldShow(const extensions::Extension* extension) const; 214 215 // Handle installing OS hooks for Web App installs from chrome://apps page. 216 void InstallOsHooks(const web_app::AppId& app_id); 217 218 // The apps are represented in the extensions model, which 219 // outlives us since it's owned by our containing profile. 220 extensions::ExtensionService* const extension_service_; 221 222 // The apps are represented in the web apps model, which outlives us since 223 // it's owned by our containing profile. Populated iff 224 // features::kDesktopPWAsWithoutExtensions is enabled. 225 web_app::WebAppProvider* const web_app_provider_; 226 227 ScopedObserver<web_app::AppRegistrar, web_app::AppRegistrarObserver> 228 web_apps_observer_{this}; 229 230 // We monitor changes to the extension system so that we can reload the apps 231 // when necessary. 232 content::NotificationRegistrar registrar_; 233 234 // Monitor extension preference changes so that the Web UI can be notified. 235 PrefChangeRegistrar extension_pref_change_registrar_; 236 237 // Monitor the local state pref to control the app launcher promo. 238 PrefChangeRegistrar local_state_pref_change_registrar_; 239 240 // Used to show confirmation UI for uninstalling extensions in incognito mode. 241 std::unique_ptr<extensions::ExtensionUninstallDialog> 242 extension_uninstall_dialog_; 243 244 // Used to show confirmation UI for enabling extensions. 245 std::unique_ptr<ExtensionEnableFlow> extension_enable_flow_; 246 247 // The ids of apps to show on the NTP. 248 std::set<std::string> visible_apps_; 249 250 // The id of the extension we are prompting the user about (either enable or 251 // uninstall). 252 std::string extension_id_prompting_; 253 254 // When true, we ignore changes to the underlying data rather than immediately 255 // refreshing. This is useful when making many batch updates to avoid flicker. 256 bool ignore_changes_; 257 258 // When populated, we have attempted to install a bookmark app, and are still 259 // waiting to hear about success or failure from the extensions system. 260 base::Optional<syncer::StringOrdinal> 261 attempting_web_app_install_page_ordinal_; 262 263 // True if we have executed HandleGetApps() at least once. 264 bool has_loaded_apps_; 265 266 // The ID of the app to be highlighted on the NTP (i.e. shown on the page 267 // and pulsed). This is done for new installs. The actual higlighting occurs 268 // when the app is added to the page (via getAppsCallback or appAdded). 269 std::string highlight_app_id_; 270 271 // Used for favicon loading tasks. 272 base::CancelableTaskTracker cancelable_task_tracker_; 273 274 // Used for passing callbacks. 275 base::WeakPtrFactory<AppLauncherHandler> weak_ptr_factory_{this}; 276 277 DISALLOW_COPY_AND_ASSIGN(AppLauncherHandler); 278 }; 279 280 #endif // CHROME_BROWSER_UI_WEBUI_NTP_APP_LAUNCHER_HANDLER_H_ 281