Home | History | Annotate | Download | only in web_view
      1 // Copyright 2014 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 EXTENSIONS_BROWSER_GUEST_VIEW_WEB_VIEW_WEB_VIEW_GUEST_H_
      6 #define EXTENSIONS_BROWSER_GUEST_VIEW_WEB_VIEW_WEB_VIEW_GUEST_H_
      7 
      8 #include <vector>
      9 
     10 #include "base/observer_list.h"
     11 #include "content/public/browser/javascript_dialog_manager.h"
     12 #include "content/public/browser/notification_observer.h"
     13 #include "content/public/browser/notification_registrar.h"
     14 #include "extensions/browser/guest_view/guest_view.h"
     15 #include "extensions/browser/guest_view/web_view/javascript_dialog_helper.h"
     16 #include "extensions/browser/guest_view/web_view/web_view_find_helper.h"
     17 #include "extensions/browser/guest_view/web_view/web_view_guest_delegate.h"
     18 #include "extensions/browser/guest_view/web_view/web_view_permission_helper.h"
     19 #include "extensions/browser/guest_view/web_view/web_view_permission_types.h"
     20 #include "extensions/browser/script_executor.h"
     21 
     22 namespace blink {
     23 struct WebFindOptions;
     24 }  // nanespace blink
     25 
     26 namespace extensions {
     27 
     28 class WebViewInternalFindFunction;
     29 
     30 // A WebViewGuest provides the browser-side implementation of the <webview> API
     31 // and manages the dispatch of <webview> extension events. WebViewGuest is
     32 // created on attachment. That is, when a guest WebContents is associated with
     33 // a particular embedder WebContents. This happens on either initial navigation
     34 // or through the use of the New Window API, when a new window is attached to
     35 // a particular <webview>.
     36 class WebViewGuest : public GuestView<WebViewGuest>,
     37                      public content::NotificationObserver {
     38  public:
     39   static GuestViewBase* Create(content::BrowserContext* browser_context,
     40                                int guest_instance_id);
     41 
     42   // For WebViewGuest, we create special guest processes, which host the
     43   // tag content separately from the main application that embeds the tag.
     44   // A <webview> can specify both the partition name and whether the storage
     45   // for that partition should be persisted. Each tag gets a SiteInstance with
     46   // a specially formatted URL, based on the application it is hosted by and
     47   // the partition requested by it. The format for that URL is:
     48   // chrome-guest://partition_domain/persist?partition_name
     49   static bool GetGuestPartitionConfigForSite(const GURL& site,
     50                                              std::string* partition_domain,
     51                                              std::string* partition_name,
     52                                              bool* in_memory);
     53 
     54   // Returns guestview::kInstanceIDNone if |contents| does not correspond to a
     55   // WebViewGuest.
     56   static int GetViewInstanceId(content::WebContents* contents);
     57 
     58   static const char Type[];
     59 
     60   // Request navigating the guest to the provided |src| URL.
     61   void NavigateGuest(const std::string& src);
     62 
     63   // Shows the context menu for the guest.
     64   // |items| acts as a filter. This restricts the current context's default
     65   // menu items to contain only the items from |items|.
     66   // |items| == NULL means no filtering will be applied.
     67   void ShowContextMenu(
     68       int request_id,
     69       const WebViewGuestDelegate::MenuItemVector* items);
     70 
     71   // Sets the frame name of the guest.
     72   void SetName(const std::string& name);
     73 
     74   // Set the zoom factor.
     75   void SetZoom(double zoom_factor);
     76 
     77   // Sets the transparency of the guest.
     78   void SetAllowTransparency(bool allow);
     79 
     80   // GuestViewBase implementation.
     81   virtual const char* GetAPINamespace() const OVERRIDE;
     82   virtual int GetTaskPrefix() const OVERRIDE;
     83   virtual void CreateWebContents(
     84       const std::string& embedder_extension_id,
     85       int embedder_render_process_id,
     86       const GURL& embedder_site_url,
     87       const base::DictionaryValue& create_params,
     88       const WebContentsCreatedCallback& callback) OVERRIDE;
     89   virtual void DidAttachToEmbedder() OVERRIDE;
     90   virtual void DidInitialize() OVERRIDE;
     91   virtual void DidStopLoading() OVERRIDE;
     92   virtual void EmbedderDestroyed() OVERRIDE;
     93   virtual void GuestDestroyed() OVERRIDE;
     94   virtual void GuestReady() OVERRIDE;
     95   virtual void GuestSizeChangedDueToAutoSize(
     96       const gfx::Size& old_size,
     97       const gfx::Size& new_size) OVERRIDE;
     98   virtual bool IsAutoSizeSupported() const OVERRIDE;
     99   virtual bool IsDragAndDropEnabled() const OVERRIDE;
    100   virtual void WillAttachToEmbedder() OVERRIDE;
    101   virtual void WillDestroy() OVERRIDE;
    102 
    103   // WebContentsDelegate implementation.
    104   virtual bool AddMessageToConsole(content::WebContents* source,
    105                                    int32 level,
    106                                    const base::string16& message,
    107                                    int32 line_no,
    108                                    const base::string16& source_id) OVERRIDE;
    109   virtual void LoadProgressChanged(content::WebContents* source,
    110                                    double progress) OVERRIDE;
    111   virtual void CloseContents(content::WebContents* source) OVERRIDE;
    112   virtual void FindReply(content::WebContents* source,
    113                          int request_id,
    114                          int number_of_matches,
    115                          const gfx::Rect& selection_rect,
    116                          int active_match_ordinal,
    117                          bool final_update) OVERRIDE;
    118   virtual bool HandleContextMenu(
    119       const content::ContextMenuParams& params) OVERRIDE;
    120   virtual void HandleKeyboardEvent(
    121       content::WebContents* source,
    122       const content::NativeWebKeyboardEvent& event) OVERRIDE;
    123   virtual void RendererResponsive(content::WebContents* source) OVERRIDE;
    124   virtual void RendererUnresponsive(content::WebContents* source) OVERRIDE;
    125   virtual void RequestMediaAccessPermission(
    126       content::WebContents* source,
    127       const content::MediaStreamRequest& request,
    128       const content::MediaResponseCallback& callback) OVERRIDE;
    129   virtual bool CheckMediaAccessPermission(
    130       content::WebContents* source,
    131       const GURL& security_origin,
    132       content::MediaStreamType type) OVERRIDE;
    133   virtual void CanDownload(content::RenderViewHost* render_view_host,
    134                            const GURL& url,
    135                            const std::string& request_method,
    136                            const base::Callback<void(bool)>& callback) OVERRIDE;
    137   virtual content::JavaScriptDialogManager*
    138       GetJavaScriptDialogManager() OVERRIDE;
    139   virtual content::ColorChooser* OpenColorChooser(
    140       content::WebContents* web_contents,
    141       SkColor color,
    142       const std::vector<content::ColorSuggestion>& suggestions) OVERRIDE;
    143   virtual void AddNewContents(content::WebContents* source,
    144                               content::WebContents* new_contents,
    145                               WindowOpenDisposition disposition,
    146                               const gfx::Rect& initial_pos,
    147                               bool user_gesture,
    148                               bool* was_blocked) OVERRIDE;
    149   virtual content::WebContents* OpenURLFromTab(
    150       content::WebContents* source,
    151       const content::OpenURLParams& params) OVERRIDE;
    152   virtual void WebContentsCreated(content::WebContents* source_contents,
    153                                   int opener_render_frame_id,
    154                                   const base::string16& frame_name,
    155                                   const GURL& target_url,
    156                                   content::WebContents* new_contents) OVERRIDE;
    157 
    158   // BrowserPluginGuestDelegate implementation.
    159   virtual content::WebContents* CreateNewGuestWindow(
    160       const content::WebContents::CreateParams& create_params) OVERRIDE;
    161   virtual void RequestPointerLockPermission(
    162       bool user_gesture,
    163       bool last_unlocked_by_target,
    164       const base::Callback<void(bool)>& callback) OVERRIDE;
    165   // NotificationObserver implementation.
    166   virtual void Observe(int type,
    167                        const content::NotificationSource& source,
    168                        const content::NotificationDetails& details) OVERRIDE;
    169 
    170   // Returns the current zoom factor.
    171   double GetZoom();
    172 
    173   // Begin or continue a find request.
    174   void Find(const base::string16& search_text,
    175             const blink::WebFindOptions& options,
    176             scoped_refptr<WebViewInternalFindFunction> find_function);
    177 
    178   // Conclude a find request to clear highlighting.
    179   void StopFinding(content::StopFindAction);
    180 
    181   // If possible, navigate the guest to |relative_index| entries away from the
    182   // current navigation entry.
    183   void Go(int relative_index);
    184 
    185   // Reload the guest.
    186   void Reload();
    187 
    188   typedef base::Callback<void(bool /* allow */,
    189                               const std::string& /* user_input */)>
    190       PermissionResponseCallback;
    191   int RequestPermission(
    192       WebViewPermissionType permission_type,
    193       const base::DictionaryValue& request_info,
    194       const PermissionResponseCallback& callback,
    195       bool allowed_by_default);
    196 
    197   // Requests Geolocation Permission from the embedder.
    198   void RequestGeolocationPermission(int bridge_id,
    199                                     const GURL& requesting_frame,
    200                                     bool user_gesture,
    201                                     const base::Callback<void(bool)>& callback);
    202   void CancelGeolocationPermissionRequest(int bridge_id);
    203 
    204   // Called when file system access is requested by the guest content using the
    205   // HTML5 file system API in main thread, or a worker thread.
    206   // The request is plumbed through the <webview> permission request API. The
    207   // request will be:
    208   // - Allowed if the embedder explicitly allowed it.
    209   // - Denied if the embedder explicitly denied.
    210   // - Determined by the guest's content settings if the embedder does not
    211   // perform an explicit action.
    212   void RequestFileSystemPermission(const GURL& url,
    213                                    bool allowed_by_default,
    214                                    const base::Callback<void(bool)>& callback);
    215 
    216   // Overrides the user agent for this guest.
    217   // This affects subsequent guest navigations.
    218   void SetUserAgentOverride(const std::string& user_agent_override);
    219 
    220   // Stop loading the guest.
    221   void Stop();
    222 
    223   // Kill the guest process.
    224   void Terminate();
    225 
    226   // Clears data in the storage partition of this guest.
    227   //
    228   // Partition data that are newer than |removal_since| will be removed.
    229   // |removal_mask| corresponds to bitmask in StoragePartition::RemoveDataMask.
    230   bool ClearData(const base::Time remove_since,
    231                  uint32 removal_mask,
    232                  const base::Closure& callback);
    233 
    234   ScriptExecutor* script_executor() { return script_executor_.get(); }
    235 
    236  private:
    237   friend class WebViewPermissionHelper;
    238   WebViewGuest(content::BrowserContext* browser_context,
    239                int guest_instance_id);
    240 
    241   virtual ~WebViewGuest();
    242 
    243   void AttachWebViewHelpers(content::WebContents* contents);
    244 
    245   void OnWebViewNewWindowResponse(int new_window_instance_id,
    246                                   bool allow,
    247                                   const std::string& user_input);
    248 
    249   // WebContentsObserver implementation.
    250   virtual void DidCommitProvisionalLoadForFrame(
    251       content::RenderFrameHost* render_frame_host,
    252       const GURL& url,
    253       ui::PageTransition transition_type) OVERRIDE;
    254   virtual void DidFailProvisionalLoad(
    255       content::RenderFrameHost* render_frame_host,
    256       const GURL& validated_url,
    257       int error_code,
    258       const base::string16& error_description) OVERRIDE;
    259   virtual void DidStartProvisionalLoadForFrame(
    260       content::RenderFrameHost* render_frame_host,
    261       const GURL& validated_url,
    262       bool is_error_page,
    263       bool is_iframe_srcdoc) OVERRIDE;
    264   virtual void DocumentLoadedInFrame(
    265       content::RenderFrameHost* render_frame_host) OVERRIDE;
    266   virtual bool OnMessageReceived(
    267       const IPC::Message& message,
    268       content::RenderFrameHost* render_frame_host) OVERRIDE;
    269   virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE;
    270   virtual void UserAgentOverrideSet(const std::string& user_agent) OVERRIDE;
    271 
    272   // Informs the embedder of a frame name change.
    273   void ReportFrameNameChange(const std::string& name);
    274 
    275   // Called after the load handler is called in the guest's main frame.
    276   void LoadHandlerCalled();
    277 
    278   // Called when a redirect notification occurs.
    279   void LoadRedirect(const GURL& old_url,
    280                     const GURL& new_url,
    281                     bool is_top_level);
    282 
    283   void PushWebViewStateToIOThread();
    284   static void RemoveWebViewStateFromIOThread(
    285       content::WebContents* web_contents);
    286 
    287   void LoadURLWithParams(const GURL& url,
    288                          const content::Referrer& referrer,
    289                          ui::PageTransition transition_type,
    290                          content::WebContents* web_contents);
    291 
    292   void RequestNewWindowPermission(
    293       WindowOpenDisposition disposition,
    294       const gfx::Rect& initial_bounds,
    295       bool user_gesture,
    296       content::WebContents* new_contents);
    297 
    298   // Destroy unattached new windows that have been opened by this
    299   // WebViewGuest.
    300   void DestroyUnattachedWindows();
    301 
    302   // Requests resolution of a potentially relative URL.
    303   GURL ResolveURL(const std::string& src);
    304 
    305   // Notification that a load in the guest resulted in abort. Note that |url|
    306   // may be invalid.
    307   void LoadAbort(bool is_top_level,
    308                  const GURL& url,
    309                  const std::string& error_type);
    310 
    311   void OnFrameNameChanged(bool is_top_level, const std::string& name);
    312 
    313   // Creates a new guest window owned by this WebViewGuest.
    314   void CreateNewGuestWebViewWindow(const content::OpenURLParams& params);
    315 
    316   void NewGuestWebViewCallback(const content::OpenURLParams& params,
    317                                content::WebContents* guest_web_contents);
    318 
    319   bool HandleKeyboardShortcuts(const content::NativeWebKeyboardEvent& event);
    320 
    321   void SetUpAutoSize();
    322 
    323   // Handles find requests and replies for the webview find API.
    324   WebViewFindHelper find_helper_;
    325 
    326   ObserverList<ScriptExecutionObserver> script_observers_;
    327   scoped_ptr<ScriptExecutor> script_executor_;
    328 
    329   content::NotificationRegistrar notification_registrar_;
    330 
    331   // True if the user agent is overridden.
    332   bool is_overriding_user_agent_;
    333 
    334   // Stores the window name of the main frame of the guest.
    335   std::string name_;
    336 
    337   // Stores whether the contents of the guest can be transparent.
    338   bool guest_opaque_;
    339 
    340   // Handles the JavaScript dialog requests.
    341   JavaScriptDialogHelper javascript_dialog_helper_;
    342 
    343   // Handels permission requests.
    344   scoped_ptr<WebViewPermissionHelper> web_view_permission_helper_;
    345 
    346   scoped_ptr<WebViewGuestDelegate> web_view_guest_delegate_;
    347 
    348   // Tracks the name, and target URL of the new window. Once the first
    349   // navigation commits, we no longer track this information.
    350   struct NewWindowInfo {
    351     GURL url;
    352     std::string name;
    353     bool changed;
    354     NewWindowInfo(const GURL& url, const std::string& name) :
    355         url(url),
    356         name(name),
    357         changed(false) {}
    358   };
    359 
    360   typedef std::map<WebViewGuest*, NewWindowInfo> PendingWindowMap;
    361   PendingWindowMap pending_new_windows_;
    362 
    363   DISALLOW_COPY_AND_ASSIGN(WebViewGuest);
    364 };
    365 
    366 }  // namespace extensions
    367 
    368 #endif  // EXTENSIONS_BROWSER_GUEST_VIEW_WEB_VIEW_WEB_VIEW_GUEST_H_
    369