1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124

fuchsia_web / webengine / browser / navigation_controller_impl.h [blame]

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

#ifndef FUCHSIA_WEB_WEBENGINE_BROWSER_NAVIGATION_CONTROLLER_IMPL_H_
#define FUCHSIA_WEB_WEBENGINE_BROWSER_NAVIGATION_CONTROLLER_IMPL_H_

#include <fuchsia/web/cpp/fidl.h>
#include <lib/fidl/cpp/binding_set.h>

#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "components/favicon/core/favicon_driver_observer.h"
#include "content/public/browser/web_contents_observer.h"
#include "fuchsia_web/webengine/web_engine_export.h"
#include "net/base/net_errors.h"

namespace content {
class NavigationEntry;
class NavigationHandle;
class WebContents;
}  // namespace content

// Implementation of fuchsia.web.NavigationController for content::WebContents.
class NavigationControllerImpl final
    : public fuchsia::web::NavigationController,
      public content::WebContentsObserver,
      public favicon::FaviconDriverObserver {
 public:
  NavigationControllerImpl(content::WebContents* web_contents,
                           void* parent_for_trace_flow);

  NavigationControllerImpl(const NavigationControllerImpl&) = delete;
  NavigationControllerImpl& operator=(const NavigationControllerImpl&) = delete;

  ~NavigationControllerImpl() override;

  void AddBinding(
      fidl::InterfaceRequest<fuchsia::web::NavigationController> controller);

  void SetEventListener(
      fidl::InterfaceHandle<fuchsia::web::NavigationEventListener> listener,
      fuchsia::web::NavigationEventListenerFlags flags);

 private:
  // Returns a NavigationState reflecting the current state of |web_contents_|'s
  // visible navigation entry, taking into account |is_main_document_loaded_|
  // and |uncommitted_load_error_| states.
  fuchsia::web::NavigationState GetVisibleNavigationState() const;

  // Processes the most recent changes to the browser's navigation state and
  // triggers the publishing of change events.
  void OnNavigationEntryChanged();

  // Sends |pending_navigation_event_| to the observer if there are any changes
  // to be reported.
  void MaybeSendNavigationEvent();

  // fuchsia::web::NavigationController implementation.
  void LoadUrl(std::string url,
               fuchsia::web::LoadUrlParams params,
               LoadUrlCallback callback) override;
  void GoBack() override;
  void GoForward() override;
  void Stop() override;
  void Reload(fuchsia::web::ReloadType type) override;

  // content::WebContentsObserver implementation.
  void TitleWasSet(content::NavigationEntry*) override;
  void PrimaryMainDocumentElementAvailable() override;
  void DidFinishLoad(content::RenderFrameHost* render_frame_host,
                     const GURL& validated_url) override;
  void PrimaryMainFrameRenderProcessGone(
      base::TerminationStatus status) override;
  void DidStartNavigation(
      content::NavigationHandle* navigation_handle) override;
  void DidFinishNavigation(
      content::NavigationHandle* navigation_handle) override;

  // favicon::FaviconDriverObserver implementation.
  void OnFaviconUpdated(favicon::FaviconDriver* favicon_driver,
                        NotificationIconType notification_icon_type,
                        const GURL& icon_url,
                        bool icon_url_changed,
                        const gfx::Image& image) override;

  const raw_ptr<void> parent_for_trace_flow_;
  const raw_ptr<content::WebContents> web_contents_;

  // NavigationController client bindings.
  fidl::BindingSet<fuchsia::web::NavigationController> controller_bindings_;

  // Fields used to dispatch events to the NavigationEventListener.
  fuchsia::web::NavigationEventListenerPtr navigation_listener_;
  fuchsia::web::NavigationState previous_navigation_state_;
  fuchsia::web::NavigationState pending_navigation_event_;
  bool waiting_for_navigation_event_ack_ = false;

  // True once the main document finishes loading and there are no outstanding
  // navigations.
  bool is_main_document_loaded_ = false;
  raw_ptr<content::NavigationHandle> active_navigation_ = nullptr;

  // True if navigation failed due to an error during page load.
  bool uncommitted_load_error_ = false;

  // Network error code from the last navigation attempt.
  net::Error last_error_code_ = net::OK;

  // Set to true  when NavigationEventListenerFlags::FAVICON flag
  // was passed to the last SetEventListener() call, i.e. favicon reporting is
  // enabled.
  bool send_favicon_ = false;

  base::WeakPtrFactory<NavigationControllerImpl> weak_factory_;
};

// Exposed to allow unit-testing of NavigationState differencing.
WEB_ENGINE_EXPORT void DiffNavigationEntriesForTest(
    const fuchsia::web::NavigationState& old_entry,
    const fuchsia::web::NavigationState& new_entry,
    fuchsia::web::NavigationState* difference);

#endif  // FUCHSIA_WEB_WEBENGINE_BROWSER_NAVIGATION_CONTROLLER_IMPL_H_