chromium/ash/webui/shimless_rma/backend/external_app_dialog.h

// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef ASH_WEBUI_SHIMLESS_RMA_BACKEND_EXTERNAL_APP_DIALOG_H_
#define ASH_WEBUI_SHIMLESS_RMA_BACKEND_EXTERNAL_APP_DIALOG_H_

#include <string>

#include "ash/webui/shimless_rma/backend/shimless_rma_delegate.h"
#include "base/functional/callback_forward.h"
#include "base/logging.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "content/public/browser/web_contents_observer.h"
#include "ui/web_dialogs/web_dialog_delegate.h"
#include "url/gurl.h"

namespace content {
class BrowserContext;
}  // namespace content

namespace views {
class WebDialogView;
class Widget;
}  // namespace views

namespace ash::shimless_rma {

// Provides a dialog to show external apps on shimless rma screen. It creates a
// WebDialogView, and disables some API (e.g. opening tabs, opening file
// chooser) to prevent them being used in shimless rma screen.
class ExternalAppDialog : public ui::WebDialogDelegate,
                          public content::WebContentsObserver {
 public:
  using ConsoleLogCallback =
      base::RepeatingCallback<void(logging::LogSeverity log_level,
                                   const std::u16string& message,
                                   int32_t line_no,
                                   const std::u16string& source_id)>;
  // Params for a dialog.
  struct InitParams {
    InitParams();
    InitParams(const InitParams&) = delete;
    InitParams& operator=(const InitParams&) = delete;
    ~InitParams();

    // The BrowserContext for the dialog.
    raw_ptr<content::BrowserContext> context;
    // App name.
    std::string app_name;
    // The url of the dialog content.
    GURL content_url;
    // Callback for handling the console log from the app.
    ConsoleLogCallback on_console_log;
    // The shimless RMA delegate for accessing //chrome functions.
    base::WeakPtr<ShimlessRmaDelegate> shimless_rma_delegate;
  };

  // Shows the dialog. Shouldn't be called if last dialog opened by this
  // function is still open.
  static void Show(const InitParams& params);

  // Returns the WebContents of the dialog. Could be `nullptr` if WebContents is
  // not ready.
  static content::WebContents* GetWebContents();

  // Sets a callback to mock `Show` in test.
  static void SetMockShowForTesting(
      base::RepeatingCallback<void(const InitParams& params)> callback);

  // Closes the open dialog in test. Does nothing if there is no open dialog.
  static void CloseForTesting();

 protected:
  explicit ExternalAppDialog(const InitParams& params);
  ExternalAppDialog(const ExternalAppDialog&) = delete;
  ExternalAppDialog& operator=(const ExternalAppDialog&) = delete;

  ~ExternalAppDialog() override;

 private:
  // ui::WebDialogDelegate overrides:
  void GetDialogSize(gfx::Size* size) const override;
  void OnLoadingStateChanged(content::WebContents* source) override;
  void RequestMediaAccessPermission(
      content::WebContents* web_contents,
      const content::MediaStreamRequest& request,
      content::MediaResponseCallback callback) override;

  // content::WebContentsObserver overrides:
  void OnDidAddMessageToConsole(
      content::RenderFrameHost* source_frame,
      blink::mojom::ConsoleMessageLevel log_level,
      const std::u16string& message,
      int32_t line_no,
      const std::u16string& source_id,
      const std::optional<std::u16string>& untrusted_stack_trace) override;

  // Set to true once setup for webcontent is initialized.
  bool has_web_content_setup_ = false;
  // views::WebDialogView that owns this delegate.
  raw_ptr<views::WebDialogView> web_dialog_view_;
  // views::Widget that owns this delegate.
  raw_ptr<views::Widget> widget_;
  // Delegate for accessing //chrome.
  base::WeakPtr<ShimlessRmaDelegate> shimless_rma_delegate_;
  // Callback for handling the console log from the app.
  ConsoleLogCallback on_console_log_;
};

}  // namespace ash::shimless_rma

#endif  // ASH_WEBUI_SHIMLESS_RMA_BACKEND_EXTERNAL_APP_DIALOG_H_