common_web_contents_delegate.cc 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685
  1. // Copyright (c) 2015 GitHub, Inc.
  2. // Use of this source code is governed by the MIT license that can be
  3. // found in the LICENSE file.
  4. #include "shell/browser/common_web_contents_delegate.h"
  5. #include <memory>
  6. #include <set>
  7. #include <string>
  8. #include <utility>
  9. #include <vector>
  10. #include "base/files/file_util.h"
  11. #include "base/json/json_reader.h"
  12. #include "base/task/post_task.h"
  13. #include "base/threading/scoped_blocking_call.h"
  14. #include "base/threading/sequenced_task_runner_handle.h"
  15. #include "chrome/browser/ssl/security_state_tab_helper.h"
  16. #include "chrome/common/pref_names.h"
  17. #include "components/prefs/pref_service.h"
  18. #include "components/prefs/scoped_user_pref_update.h"
  19. #include "components/security_state/content/content_utils.h"
  20. #include "components/security_state/core/security_state.h"
  21. #include "content/browser/renderer_host/render_widget_host_view_base.h" // nogncheck
  22. #include "content/public/browser/browser_thread.h"
  23. #include "content/public/browser/child_process_security_policy.h"
  24. #include "content/public/browser/file_select_listener.h"
  25. #include "content/public/browser/render_process_host.h"
  26. #include "content/public/browser/render_view_host.h"
  27. #include "content/public/browser/render_widget_host.h"
  28. #include "content/public/browser/security_style_explanation.h"
  29. #include "content/public/browser/security_style_explanations.h"
  30. #include "printing/buildflags/buildflags.h"
  31. #include "shell/browser/atom_browser_client.h"
  32. #include "shell/browser/atom_browser_context.h"
  33. #include "shell/browser/native_window.h"
  34. #include "shell/browser/ui/file_dialog.h"
  35. #include "shell/browser/web_contents_preferences.h"
  36. #include "shell/browser/web_dialog_helper.h"
  37. #include "shell/common/atom_constants.h"
  38. #include "shell/common/options_switches.h"
  39. #include "storage/browser/file_system/isolated_context.h"
  40. #if BUILDFLAG(ENABLE_COLOR_CHOOSER)
  41. #include "chrome/browser/ui/color_chooser.h"
  42. #endif
  43. #if BUILDFLAG(ENABLE_OSR)
  44. #include "shell/browser/osr/osr_web_contents_view.h"
  45. #endif
  46. #if BUILDFLAG(ENABLE_PRINTING)
  47. #include "chrome/browser/printing/print_view_manager_basic.h"
  48. #include "components/printing/browser/print_manager_utils.h"
  49. #include "shell/browser/printing/print_preview_message_handler.h"
  50. #endif
  51. #if BUILDFLAG(ENABLE_PICTURE_IN_PICTURE)
  52. #include "chrome/browser/picture_in_picture/picture_in_picture_window_manager.h"
  53. #endif
  54. #if BUILDFLAG(ENABLE_PDF_VIEWER)
  55. #include "components/pdf/browser/pdf_web_contents_helper.h" // nogncheck
  56. #include "shell/browser/electron_pdf_web_contents_helper_client.h"
  57. #endif
  58. using content::BrowserThread;
  59. namespace electron {
  60. namespace {
  61. const char kRootName[] = "<root>";
  62. struct FileSystem {
  63. FileSystem() = default;
  64. FileSystem(const std::string& type,
  65. const std::string& file_system_name,
  66. const std::string& root_url,
  67. const std::string& file_system_path)
  68. : type(type),
  69. file_system_name(file_system_name),
  70. root_url(root_url),
  71. file_system_path(file_system_path) {}
  72. std::string type;
  73. std::string file_system_name;
  74. std::string root_url;
  75. std::string file_system_path;
  76. };
  77. std::string RegisterFileSystem(content::WebContents* web_contents,
  78. const base::FilePath& path) {
  79. auto* isolated_context = storage::IsolatedContext::GetInstance();
  80. std::string root_name(kRootName);
  81. storage::IsolatedContext::ScopedFSHandle file_system =
  82. isolated_context->RegisterFileSystemForPath(
  83. storage::kFileSystemTypeNativeLocal, std::string(), path, &root_name);
  84. content::ChildProcessSecurityPolicy* policy =
  85. content::ChildProcessSecurityPolicy::GetInstance();
  86. content::RenderViewHost* render_view_host = web_contents->GetRenderViewHost();
  87. int renderer_id = render_view_host->GetProcess()->GetID();
  88. policy->GrantReadFileSystem(renderer_id, file_system.id());
  89. policy->GrantWriteFileSystem(renderer_id, file_system.id());
  90. policy->GrantCreateFileForFileSystem(renderer_id, file_system.id());
  91. policy->GrantDeleteFromFileSystem(renderer_id, file_system.id());
  92. if (!policy->CanReadFile(renderer_id, path))
  93. policy->GrantReadFile(renderer_id, path);
  94. return file_system.id();
  95. }
  96. FileSystem CreateFileSystemStruct(content::WebContents* web_contents,
  97. const std::string& file_system_id,
  98. const std::string& file_system_path,
  99. const std::string& type) {
  100. const GURL origin = web_contents->GetURL().GetOrigin();
  101. std::string file_system_name =
  102. storage::GetIsolatedFileSystemName(origin, file_system_id);
  103. std::string root_url = storage::GetIsolatedFileSystemRootURIString(
  104. origin, file_system_id, kRootName);
  105. return FileSystem(type, file_system_name, root_url, file_system_path);
  106. }
  107. std::unique_ptr<base::DictionaryValue> CreateFileSystemValue(
  108. const FileSystem& file_system) {
  109. std::unique_ptr<base::DictionaryValue> file_system_value(
  110. new base::DictionaryValue());
  111. file_system_value->SetString("type", file_system.type);
  112. file_system_value->SetString("fileSystemName", file_system.file_system_name);
  113. file_system_value->SetString("rootURL", file_system.root_url);
  114. file_system_value->SetString("fileSystemPath", file_system.file_system_path);
  115. return file_system_value;
  116. }
  117. void WriteToFile(const base::FilePath& path, const std::string& content) {
  118. base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
  119. base::BlockingType::WILL_BLOCK);
  120. DCHECK(!path.empty());
  121. base::WriteFile(path, content.data(), content.size());
  122. }
  123. void AppendToFile(const base::FilePath& path, const std::string& content) {
  124. base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
  125. base::BlockingType::WILL_BLOCK);
  126. DCHECK(!path.empty());
  127. base::AppendToFile(path, content.data(), content.size());
  128. }
  129. PrefService* GetPrefService(content::WebContents* web_contents) {
  130. auto* context = web_contents->GetBrowserContext();
  131. return static_cast<electron::AtomBrowserContext*>(context)->prefs();
  132. }
  133. std::map<std::string, std::string> GetAddedFileSystemPaths(
  134. content::WebContents* web_contents) {
  135. auto* pref_service = GetPrefService(web_contents);
  136. const base::DictionaryValue* file_system_paths_value =
  137. pref_service->GetDictionary(prefs::kDevToolsFileSystemPaths);
  138. std::map<std::string, std::string> result;
  139. if (file_system_paths_value) {
  140. base::DictionaryValue::Iterator it(*file_system_paths_value);
  141. for (; !it.IsAtEnd(); it.Advance()) {
  142. std::string type =
  143. it.value().is_string() ? it.value().GetString() : std::string();
  144. result[it.key()] = type;
  145. }
  146. }
  147. return result;
  148. }
  149. bool IsDevToolsFileSystemAdded(content::WebContents* web_contents,
  150. const std::string& file_system_path) {
  151. auto file_system_paths = GetAddedFileSystemPaths(web_contents);
  152. return file_system_paths.find(file_system_path) != file_system_paths.end();
  153. }
  154. } // namespace
  155. CommonWebContentsDelegate::CommonWebContentsDelegate()
  156. : devtools_file_system_indexer_(new DevToolsFileSystemIndexer),
  157. file_task_runner_(base::CreateSequencedTaskRunner(
  158. {base::ThreadPool(), base::MayBlock()})),
  159. weak_factory_(this) {}
  160. CommonWebContentsDelegate::~CommonWebContentsDelegate() = default;
  161. void CommonWebContentsDelegate::InitWithWebContents(
  162. content::WebContents* web_contents,
  163. AtomBrowserContext* browser_context,
  164. bool is_guest) {
  165. browser_context_ = browser_context;
  166. web_contents->SetDelegate(this);
  167. #if BUILDFLAG(ENABLE_PRINTING)
  168. PrintPreviewMessageHandler::CreateForWebContents(web_contents);
  169. printing::PrintViewManagerBasic::CreateForWebContents(web_contents);
  170. printing::CreateCompositeClientIfNeeded(web_contents,
  171. browser_context->GetUserAgent());
  172. #endif
  173. #if BUILDFLAG(ENABLE_PDF_VIEWER)
  174. pdf::PDFWebContentsHelper::CreateForWebContentsWithClient(
  175. web_contents, std::make_unique<ElectronPDFWebContentsHelperClient>());
  176. #endif
  177. // Determien whether the WebContents is offscreen.
  178. auto* web_preferences = WebContentsPreferences::From(web_contents);
  179. offscreen_ =
  180. web_preferences && web_preferences->IsEnabled(options::kOffscreen);
  181. // Create InspectableWebContents.
  182. web_contents_.reset(InspectableWebContents::Create(
  183. web_contents, browser_context->prefs(), is_guest));
  184. web_contents_->SetDelegate(this);
  185. }
  186. void CommonWebContentsDelegate::SetOwnerWindow(NativeWindow* owner_window) {
  187. SetOwnerWindow(GetWebContents(), owner_window);
  188. }
  189. void CommonWebContentsDelegate::SetOwnerWindow(
  190. content::WebContents* web_contents,
  191. NativeWindow* owner_window) {
  192. if (owner_window) {
  193. owner_window_ = owner_window->GetWeakPtr();
  194. NativeWindowRelay::CreateForWebContents(web_contents,
  195. owner_window->GetWeakPtr());
  196. } else {
  197. owner_window_ = nullptr;
  198. web_contents->RemoveUserData(NativeWindowRelay::UserDataKey());
  199. }
  200. #if BUILDFLAG(ENABLE_OSR)
  201. auto* osr_wcv = GetOffScreenWebContentsView();
  202. if (osr_wcv)
  203. osr_wcv->SetNativeWindow(owner_window);
  204. #endif
  205. }
  206. void CommonWebContentsDelegate::ResetManagedWebContents(bool async) {
  207. if (async) {
  208. // Browser context should be destroyed only after the WebContents,
  209. // this is guaranteed in the sync mode by the order of declaration,
  210. // in the async version we maintain a reference until the WebContents
  211. // is destroyed.
  212. // //electron/patches/chromium/content_browser_main_loop.patch
  213. // is required to get the right quit closure for the main message loop.
  214. base::ThreadTaskRunnerHandle::Get()->PostNonNestableTask(
  215. FROM_HERE,
  216. base::BindOnce(
  217. [](scoped_refptr<AtomBrowserContext> browser_context,
  218. std::unique_ptr<InspectableWebContents> web_contents) {
  219. web_contents.reset();
  220. },
  221. base::RetainedRef(browser_context_), std::move(web_contents_)));
  222. } else {
  223. web_contents_.reset();
  224. }
  225. }
  226. content::WebContents* CommonWebContentsDelegate::GetWebContents() const {
  227. if (!web_contents_)
  228. return nullptr;
  229. return web_contents_->GetWebContents();
  230. }
  231. content::WebContents* CommonWebContentsDelegate::GetDevToolsWebContents()
  232. const {
  233. if (!web_contents_)
  234. return nullptr;
  235. return web_contents_->GetDevToolsWebContents();
  236. }
  237. #if BUILDFLAG(ENABLE_OSR)
  238. OffScreenWebContentsView*
  239. CommonWebContentsDelegate::GetOffScreenWebContentsView() const {
  240. return nullptr;
  241. }
  242. #endif
  243. content::WebContents* CommonWebContentsDelegate::OpenURLFromTab(
  244. content::WebContents* source,
  245. const content::OpenURLParams& params) {
  246. content::NavigationController::LoadURLParams load_url_params(params.url);
  247. load_url_params.referrer = params.referrer;
  248. load_url_params.transition_type = params.transition;
  249. load_url_params.extra_headers = params.extra_headers;
  250. load_url_params.should_replace_current_entry =
  251. params.should_replace_current_entry;
  252. load_url_params.is_renderer_initiated = params.is_renderer_initiated;
  253. load_url_params.initiator_origin = params.initiator_origin;
  254. load_url_params.should_clear_history_list = true;
  255. source->GetController().LoadURLWithParams(load_url_params);
  256. return source;
  257. }
  258. bool CommonWebContentsDelegate::CanOverscrollContent() {
  259. return false;
  260. }
  261. content::ColorChooser* CommonWebContentsDelegate::OpenColorChooser(
  262. content::WebContents* web_contents,
  263. SkColor color,
  264. const std::vector<blink::mojom::ColorSuggestionPtr>& suggestions) {
  265. #if BUILDFLAG(ENABLE_COLOR_CHOOSER)
  266. return chrome::ShowColorChooser(web_contents, color);
  267. #else
  268. return nullptr;
  269. #endif
  270. }
  271. void CommonWebContentsDelegate::RunFileChooser(
  272. content::RenderFrameHost* render_frame_host,
  273. std::unique_ptr<content::FileSelectListener> listener,
  274. const blink::mojom::FileChooserParams& params) {
  275. if (!web_dialog_helper_)
  276. web_dialog_helper_ =
  277. std::make_unique<WebDialogHelper>(owner_window(), offscreen_);
  278. web_dialog_helper_->RunFileChooser(render_frame_host, std::move(listener),
  279. params);
  280. }
  281. void CommonWebContentsDelegate::EnumerateDirectory(
  282. content::WebContents* guest,
  283. std::unique_ptr<content::FileSelectListener> listener,
  284. const base::FilePath& path) {
  285. if (!web_dialog_helper_)
  286. web_dialog_helper_ =
  287. std::make_unique<WebDialogHelper>(owner_window(), offscreen_);
  288. web_dialog_helper_->EnumerateDirectory(guest, std::move(listener), path);
  289. }
  290. void CommonWebContentsDelegate::EnterFullscreenModeForTab(
  291. content::WebContents* source,
  292. const GURL& origin,
  293. const blink::mojom::FullscreenOptions& options) {
  294. if (!owner_window_)
  295. return;
  296. if (IsFullscreenForTabOrPending(source)) {
  297. DCHECK_EQ(fullscreen_frame_, source->GetFocusedFrame());
  298. return;
  299. }
  300. SetHtmlApiFullscreen(true);
  301. owner_window_->NotifyWindowEnterHtmlFullScreen();
  302. if (native_fullscreen_) {
  303. // Explicitly trigger a view resize, as the size is not actually changing if
  304. // the browser is fullscreened, too.
  305. source->GetRenderViewHost()->GetWidget()->SynchronizeVisualProperties();
  306. }
  307. }
  308. void CommonWebContentsDelegate::ExitFullscreenModeForTab(
  309. content::WebContents* source) {
  310. if (!owner_window_)
  311. return;
  312. SetHtmlApiFullscreen(false);
  313. owner_window_->NotifyWindowLeaveHtmlFullScreen();
  314. if (native_fullscreen_) {
  315. // Explicitly trigger a view resize, as the size is not actually changing if
  316. // the browser is fullscreened, too. Chrome does this indirectly from
  317. // `chrome/browser/ui/exclusive_access/fullscreen_controller.cc`.
  318. source->GetRenderViewHost()->GetWidget()->SynchronizeVisualProperties();
  319. }
  320. }
  321. bool CommonWebContentsDelegate::IsFullscreenForTabOrPending(
  322. const content::WebContents* source) {
  323. return html_fullscreen_;
  324. }
  325. blink::SecurityStyle CommonWebContentsDelegate::GetSecurityStyle(
  326. content::WebContents* web_contents,
  327. content::SecurityStyleExplanations* security_style_explanations) {
  328. SecurityStateTabHelper* helper =
  329. SecurityStateTabHelper::FromWebContents(web_contents);
  330. DCHECK(helper);
  331. return security_state::GetSecurityStyle(helper->GetSecurityLevel(),
  332. *helper->GetVisibleSecurityState(),
  333. security_style_explanations);
  334. }
  335. bool CommonWebContentsDelegate::TakeFocus(content::WebContents* source,
  336. bool reverse) {
  337. if (source && source->GetOutermostWebContents() == source) {
  338. // If this is the outermost web contents and the user has tabbed or
  339. // shift + tabbed through all the elements, reset the focus back to
  340. // the first or last element so that it doesn't stay in the body.
  341. source->FocusThroughTabTraversal(reverse);
  342. return true;
  343. }
  344. return false;
  345. }
  346. void CommonWebContentsDelegate::DevToolsSaveToFile(const std::string& url,
  347. const std::string& content,
  348. bool save_as) {
  349. base::FilePath path;
  350. auto it = saved_files_.find(url);
  351. if (it != saved_files_.end() && !save_as) {
  352. path = it->second;
  353. } else {
  354. file_dialog::DialogSettings settings;
  355. settings.parent_window = owner_window();
  356. settings.force_detached = offscreen_;
  357. settings.title = url;
  358. settings.default_path = base::FilePath::FromUTF8Unsafe(url);
  359. if (!file_dialog::ShowSaveDialogSync(settings, &path)) {
  360. base::Value url_value(url);
  361. web_contents_->CallClientFunction("DevToolsAPI.canceledSaveURL",
  362. &url_value, nullptr, nullptr);
  363. return;
  364. }
  365. }
  366. saved_files_[url] = path;
  367. // Notify DevTools.
  368. base::Value url_value(url);
  369. base::Value file_system_path_value(path.AsUTF8Unsafe());
  370. web_contents_->CallClientFunction("DevToolsAPI.savedURL", &url_value,
  371. &file_system_path_value, nullptr);
  372. file_task_runner_->PostTask(FROM_HERE,
  373. base::BindOnce(&WriteToFile, path, content));
  374. }
  375. void CommonWebContentsDelegate::DevToolsAppendToFile(
  376. const std::string& url,
  377. const std::string& content) {
  378. auto it = saved_files_.find(url);
  379. if (it == saved_files_.end())
  380. return;
  381. // Notify DevTools.
  382. base::Value url_value(url);
  383. web_contents_->CallClientFunction("DevToolsAPI.appendedToURL", &url_value,
  384. nullptr, nullptr);
  385. file_task_runner_->PostTask(
  386. FROM_HERE, base::BindOnce(&AppendToFile, it->second, content));
  387. }
  388. void CommonWebContentsDelegate::DevToolsRequestFileSystems() {
  389. auto file_system_paths = GetAddedFileSystemPaths(GetDevToolsWebContents());
  390. if (file_system_paths.empty()) {
  391. base::ListValue empty_file_system_value;
  392. web_contents_->CallClientFunction("DevToolsAPI.fileSystemsLoaded",
  393. &empty_file_system_value, nullptr,
  394. nullptr);
  395. return;
  396. }
  397. std::vector<FileSystem> file_systems;
  398. for (const auto& file_system_path : file_system_paths) {
  399. base::FilePath path =
  400. base::FilePath::FromUTF8Unsafe(file_system_path.first);
  401. std::string file_system_id =
  402. RegisterFileSystem(GetDevToolsWebContents(), path);
  403. FileSystem file_system =
  404. CreateFileSystemStruct(GetDevToolsWebContents(), file_system_id,
  405. file_system_path.first, file_system_path.second);
  406. file_systems.push_back(file_system);
  407. }
  408. base::ListValue file_system_value;
  409. for (const auto& file_system : file_systems)
  410. file_system_value.Append(CreateFileSystemValue(file_system));
  411. web_contents_->CallClientFunction("DevToolsAPI.fileSystemsLoaded",
  412. &file_system_value, nullptr, nullptr);
  413. }
  414. void CommonWebContentsDelegate::DevToolsAddFileSystem(
  415. const std::string& type,
  416. const base::FilePath& file_system_path) {
  417. base::FilePath path = file_system_path;
  418. if (path.empty()) {
  419. std::vector<base::FilePath> paths;
  420. file_dialog::DialogSettings settings;
  421. settings.parent_window = owner_window();
  422. settings.force_detached = offscreen_;
  423. settings.properties = file_dialog::OPEN_DIALOG_OPEN_DIRECTORY;
  424. if (!file_dialog::ShowOpenDialogSync(settings, &paths))
  425. return;
  426. path = paths[0];
  427. }
  428. std::string file_system_id =
  429. RegisterFileSystem(GetDevToolsWebContents(), path);
  430. if (IsDevToolsFileSystemAdded(GetDevToolsWebContents(), path.AsUTF8Unsafe()))
  431. return;
  432. FileSystem file_system = CreateFileSystemStruct(
  433. GetDevToolsWebContents(), file_system_id, path.AsUTF8Unsafe(), type);
  434. std::unique_ptr<base::DictionaryValue> file_system_value(
  435. CreateFileSystemValue(file_system));
  436. auto* pref_service = GetPrefService(GetDevToolsWebContents());
  437. DictionaryPrefUpdate update(pref_service, prefs::kDevToolsFileSystemPaths);
  438. update.Get()->SetWithoutPathExpansion(path.AsUTF8Unsafe(),
  439. std::make_unique<base::Value>(type));
  440. web_contents_->CallClientFunction("DevToolsAPI.fileSystemAdded", nullptr,
  441. file_system_value.get(), nullptr);
  442. }
  443. void CommonWebContentsDelegate::DevToolsRemoveFileSystem(
  444. const base::FilePath& file_system_path) {
  445. if (!web_contents_)
  446. return;
  447. std::string path = file_system_path.AsUTF8Unsafe();
  448. storage::IsolatedContext::GetInstance()->RevokeFileSystemByPath(
  449. file_system_path);
  450. auto* pref_service = GetPrefService(GetDevToolsWebContents());
  451. DictionaryPrefUpdate update(pref_service, prefs::kDevToolsFileSystemPaths);
  452. update.Get()->RemoveWithoutPathExpansion(path, nullptr);
  453. base::Value file_system_path_value(path);
  454. web_contents_->CallClientFunction("DevToolsAPI.fileSystemRemoved",
  455. &file_system_path_value, nullptr, nullptr);
  456. }
  457. void CommonWebContentsDelegate::DevToolsIndexPath(
  458. int request_id,
  459. const std::string& file_system_path,
  460. const std::string& excluded_folders_message) {
  461. if (!IsDevToolsFileSystemAdded(GetDevToolsWebContents(), file_system_path)) {
  462. OnDevToolsIndexingDone(request_id, file_system_path);
  463. return;
  464. }
  465. if (devtools_indexing_jobs_.count(request_id) != 0)
  466. return;
  467. std::vector<std::string> excluded_folders;
  468. std::unique_ptr<base::Value> parsed_excluded_folders =
  469. base::JSONReader::ReadDeprecated(excluded_folders_message);
  470. if (parsed_excluded_folders && parsed_excluded_folders->is_list()) {
  471. for (const base::Value& folder_path : parsed_excluded_folders->GetList()) {
  472. if (folder_path.is_string())
  473. excluded_folders.push_back(folder_path.GetString());
  474. }
  475. }
  476. devtools_indexing_jobs_[request_id] =
  477. scoped_refptr<DevToolsFileSystemIndexer::FileSystemIndexingJob>(
  478. devtools_file_system_indexer_->IndexPath(
  479. file_system_path, excluded_folders,
  480. base::BindRepeating(
  481. &CommonWebContentsDelegate::OnDevToolsIndexingWorkCalculated,
  482. weak_factory_.GetWeakPtr(), request_id, file_system_path),
  483. base::BindRepeating(
  484. &CommonWebContentsDelegate::OnDevToolsIndexingWorked,
  485. weak_factory_.GetWeakPtr(), request_id, file_system_path),
  486. base::BindRepeating(
  487. &CommonWebContentsDelegate::OnDevToolsIndexingDone,
  488. weak_factory_.GetWeakPtr(), request_id, file_system_path)));
  489. }
  490. void CommonWebContentsDelegate::DevToolsStopIndexing(int request_id) {
  491. auto it = devtools_indexing_jobs_.find(request_id);
  492. if (it == devtools_indexing_jobs_.end())
  493. return;
  494. it->second->Stop();
  495. devtools_indexing_jobs_.erase(it);
  496. }
  497. void CommonWebContentsDelegate::DevToolsSearchInPath(
  498. int request_id,
  499. const std::string& file_system_path,
  500. const std::string& query) {
  501. if (!IsDevToolsFileSystemAdded(GetDevToolsWebContents(), file_system_path)) {
  502. OnDevToolsSearchCompleted(request_id, file_system_path,
  503. std::vector<std::string>());
  504. return;
  505. }
  506. devtools_file_system_indexer_->SearchInPath(
  507. file_system_path, query,
  508. base::BindRepeating(&CommonWebContentsDelegate::OnDevToolsSearchCompleted,
  509. weak_factory_.GetWeakPtr(), request_id,
  510. file_system_path));
  511. }
  512. void CommonWebContentsDelegate::OnDevToolsIndexingWorkCalculated(
  513. int request_id,
  514. const std::string& file_system_path,
  515. int total_work) {
  516. base::Value request_id_value(request_id);
  517. base::Value file_system_path_value(file_system_path);
  518. base::Value total_work_value(total_work);
  519. web_contents_->CallClientFunction("DevToolsAPI.indexingTotalWorkCalculated",
  520. &request_id_value, &file_system_path_value,
  521. &total_work_value);
  522. }
  523. void CommonWebContentsDelegate::OnDevToolsIndexingWorked(
  524. int request_id,
  525. const std::string& file_system_path,
  526. int worked) {
  527. base::Value request_id_value(request_id);
  528. base::Value file_system_path_value(file_system_path);
  529. base::Value worked_value(worked);
  530. web_contents_->CallClientFunction("DevToolsAPI.indexingWorked",
  531. &request_id_value, &file_system_path_value,
  532. &worked_value);
  533. }
  534. void CommonWebContentsDelegate::OnDevToolsIndexingDone(
  535. int request_id,
  536. const std::string& file_system_path) {
  537. devtools_indexing_jobs_.erase(request_id);
  538. base::Value request_id_value(request_id);
  539. base::Value file_system_path_value(file_system_path);
  540. web_contents_->CallClientFunction("DevToolsAPI.indexingDone",
  541. &request_id_value, &file_system_path_value,
  542. nullptr);
  543. }
  544. void CommonWebContentsDelegate::OnDevToolsSearchCompleted(
  545. int request_id,
  546. const std::string& file_system_path,
  547. const std::vector<std::string>& file_paths) {
  548. base::ListValue file_paths_value;
  549. for (const auto& file_path : file_paths) {
  550. file_paths_value.AppendString(file_path);
  551. }
  552. base::Value request_id_value(request_id);
  553. base::Value file_system_path_value(file_system_path);
  554. web_contents_->CallClientFunction("DevToolsAPI.searchCompleted",
  555. &request_id_value, &file_system_path_value,
  556. &file_paths_value);
  557. }
  558. void CommonWebContentsDelegate::SetHtmlApiFullscreen(bool enter_fullscreen) {
  559. // Window is already in fullscreen mode, save the state.
  560. if (enter_fullscreen && owner_window_->IsFullscreen()) {
  561. native_fullscreen_ = true;
  562. html_fullscreen_ = true;
  563. return;
  564. }
  565. // Exit html fullscreen state but not window's fullscreen mode.
  566. if (!enter_fullscreen && native_fullscreen_) {
  567. html_fullscreen_ = false;
  568. return;
  569. }
  570. // Set fullscreen on window if allowed.
  571. auto* web_preferences = WebContentsPreferences::From(GetWebContents());
  572. bool html_fullscreenable =
  573. web_preferences ? !web_preferences->IsEnabled(
  574. options::kDisableHtmlFullscreenWindowResize)
  575. : true;
  576. if (html_fullscreenable) {
  577. owner_window_->SetFullScreen(enter_fullscreen);
  578. }
  579. html_fullscreen_ = enter_fullscreen;
  580. native_fullscreen_ = false;
  581. }
  582. content::PictureInPictureResult
  583. CommonWebContentsDelegate::EnterPictureInPicture(
  584. content::WebContents* web_contents,
  585. const viz::SurfaceId& surface_id,
  586. const gfx::Size& natural_size) {
  587. #if BUILDFLAG(ENABLE_PICTURE_IN_PICTURE)
  588. return PictureInPictureWindowManager::GetInstance()->EnterPictureInPicture(
  589. web_contents, surface_id, natural_size);
  590. #else
  591. return content::PictureInPictureResult::kNotSupported;
  592. #endif
  593. }
  594. void CommonWebContentsDelegate::ExitPictureInPicture() {
  595. #if BUILDFLAG(ENABLE_PICTURE_IN_PICTURE)
  596. PictureInPictureWindowManager::GetInstance()->ExitPictureInPicture();
  597. #endif
  598. }
  599. } // namespace electron