Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2017 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 #include "content/browser/android/render_widget_host_connector.h" | |
| 6 | |
| 7 #include "content/browser/frame_host/interstitial_page_impl.h" | |
| 8 #include "content/browser/renderer_host/render_widget_host_view_android.h" | |
| 9 #include "content/browser/web_contents/web_contents_impl.h" | |
| 10 | |
| 11 namespace content { | |
| 12 | |
| 13 // Observes RenderWidgetHostViewAndroid to keep the instance up to date. | |
| 14 class RenderWidgetHostConnector::Observer | |
| 15 : public WebContentsObserver, | |
| 16 public RenderWidgetHostViewAndroid::DestructionObserver { | |
| 17 public: | |
| 18 Observer(WebContents* web_contents, RenderWidgetHostConnector* connector); | |
| 19 ~Observer() override; | |
| 20 | |
| 21 // WebContentsObserver implementation. | |
| 22 void RenderViewReady() override; | |
| 23 void RenderViewHostChanged(RenderViewHost* old_host, | |
| 24 RenderViewHost* new_host) override; | |
| 25 void DidAttachInterstitialPage() override; | |
| 26 void DidDetachInterstitialPage() override; | |
| 27 void WebContentsDestroyed() override; | |
| 28 | |
| 29 // RenderWidgetHostViewAndroid::DestructionObserver implementation. | |
| 30 void RenderWidgetHostViewDestroyed( | |
| 31 RenderWidgetHostViewAndroid* rwhva) override; | |
| 32 | |
| 33 RenderWidgetHostViewAndroid* main_rwhva() const { return main_rwhva_; } | |
| 34 RenderWidgetHostViewAndroid* interstitial_rwhva() const { | |
| 35 return interstitial_rwhva_; | |
| 36 } | |
| 37 | |
| 38 private: | |
| 39 void UpdateRenderWidgetHostView(RenderWidgetHostViewAndroid* old_rwhva, | |
| 40 RenderWidgetHostViewAndroid* new_rwhva); | |
| 41 RenderWidgetHostViewAndroid* GetRenderWidgetHostViewAndroid() const; | |
| 42 | |
| 43 RenderWidgetHostConnector* const connector_; | |
| 44 | |
| 45 // Active RenderWidgetHostView connected to this instance. | |
| 46 // Note that |main_rwhva_| points to the inactive one in the background | |
| 47 // (rather than nulled out) while an interstitial page is showing. | |
| 48 RenderWidgetHostViewAndroid* main_rwhva_; | |
| 49 RenderWidgetHostViewAndroid* interstitial_rwhva_; | |
| 50 | |
| 51 DISALLOW_COPY_AND_ASSIGN(Observer); | |
| 52 }; | |
| 53 | |
| 54 RenderWidgetHostConnector::Observer::Observer( | |
| 55 WebContents* web_contents, | |
| 56 RenderWidgetHostConnector* connector) | |
| 57 : WebContentsObserver(web_contents), | |
| 58 connector_(connector), | |
| 59 main_rwhva_(nullptr), | |
| 60 interstitial_rwhva_(nullptr) {} | |
| 61 | |
| 62 RenderWidgetHostConnector::Observer::~Observer() { | |
| 63 DCHECK(!main_rwhva_); | |
| 64 } | |
| 65 | |
| 66 void RenderWidgetHostConnector::Observer::RenderViewReady() { | |
| 67 auto* new_rwhva = GetRenderWidgetHostViewAndroid(); | |
| 68 UpdateRenderWidgetHostView(main_rwhva_, new_rwhva); | |
| 69 main_rwhva_ = new_rwhva; | |
| 70 } | |
| 71 | |
| 72 void RenderWidgetHostConnector::Observer::RenderViewHostChanged( | |
| 73 RenderViewHost* old_host, | |
| 74 RenderViewHost* new_host) { | |
| 75 auto* new_view = new_host ? static_cast<RenderWidgetHostViewAndroid*>( | |
| 76 new_host->GetWidget()->GetView()) | |
| 77 : nullptr; | |
| 78 | |
| 79 // |RenderViewHostChanged| is called only for main rwhva change. | |
| 80 // No need to update connection if an interstitial page is active. | |
| 81 if (!interstitial_rwhva_) | |
| 82 UpdateRenderWidgetHostView(main_rwhva_, new_view); | |
| 83 main_rwhva_ = new_view; | |
| 84 } | |
| 85 | |
| 86 void RenderWidgetHostConnector::Observer::DidAttachInterstitialPage() { | |
| 87 auto* new_rwhva = GetRenderWidgetHostViewAndroid(); | |
| 88 UpdateRenderWidgetHostView(main_rwhva_, new_rwhva); | |
| 89 interstitial_rwhva_ = new_rwhva; | |
| 90 } | |
| 91 | |
| 92 void RenderWidgetHostConnector::Observer::DidDetachInterstitialPage() { | |
| 93 auto* new_rwhva = GetRenderWidgetHostViewAndroid(); | |
| 94 UpdateRenderWidgetHostView(interstitial_rwhva_, new_rwhva); | |
| 95 interstitial_rwhva_ = nullptr; | |
| 96 main_rwhva_ = new_rwhva; | |
| 97 } | |
| 98 | |
| 99 void RenderWidgetHostConnector::Observer::WebContentsDestroyed() { | |
| 100 auto* cur_rwhva = interstitial_rwhva_ ? interstitial_rwhva_ : main_rwhva_; | |
| 101 DCHECK_EQ(cur_rwhva, GetRenderWidgetHostViewAndroid()); | |
| 102 UpdateRenderWidgetHostView(cur_rwhva, nullptr); | |
| 103 interstitial_rwhva_ = nullptr; | |
| 104 main_rwhva_ = nullptr; | |
| 105 delete connector_; | |
| 106 } | |
| 107 | |
| 108 void RenderWidgetHostConnector::Observer::RenderWidgetHostViewDestroyed( | |
| 109 RenderWidgetHostViewAndroid* destroyed_rwhva) { | |
| 110 // Null out the matched raw pointer here and in the connector impl to keep | |
| 111 // them from referencing the rwvha about to be destroyed. | |
| 112 if (destroyed_rwhva == interstitial_rwhva_) { | |
| 113 connector_->UpdateRenderProcessConnection(interstitial_rwhva_, nullptr); | |
| 114 interstitial_rwhva_ = nullptr; | |
| 115 } else if (destroyed_rwhva == main_rwhva_) { | |
| 116 if (!interstitial_rwhva_) | |
| 117 connector_->UpdateRenderProcessConnection(main_rwhva_, nullptr); | |
| 118 main_rwhva_ = nullptr; | |
| 119 } | |
| 120 } | |
| 121 | |
| 122 void RenderWidgetHostConnector::Observer::UpdateRenderWidgetHostView( | |
| 123 RenderWidgetHostViewAndroid* old_rwhva, | |
| 124 RenderWidgetHostViewAndroid* new_rwhva) { | |
| 125 if (old_rwhva == new_rwhva) | |
| 126 return; | |
| 127 if (old_rwhva) | |
| 128 old_rwhva->RemoveDestructionObserver(this); | |
|
boliu
2017/04/15 00:52:54
this doesn't work anymore. I think you need to obs
Jinsuk Kim
2017/04/15 01:19:07
At certain time there is (and should be) only one
boliu
2017/04/15 02:06:21
what if the non-interstitial rwhva is destroyed wh
Jinsuk Kim
2017/04/16 23:16:43
Main rwhva is not connected to ime, so its destruc
| |
| 129 if (new_rwhva) | |
| 130 new_rwhva->AddDestructionObserver(this); | |
| 131 | |
| 132 connector_->UpdateRenderProcessConnection(old_rwhva, new_rwhva); | |
| 133 } | |
| 134 | |
| 135 RenderWidgetHostViewAndroid* | |
| 136 RenderWidgetHostConnector::Observer::GetRenderWidgetHostViewAndroid() const { | |
| 137 RenderWidgetHostView* rwhv = web_contents()->GetRenderWidgetHostView(); | |
| 138 WebContentsImpl* web_contents_impl = | |
| 139 static_cast<WebContentsImpl*>(web_contents()); | |
| 140 if (web_contents_impl->ShowingInterstitialPage()) { | |
| 141 rwhv = web_contents_impl->GetInterstitialPage() | |
| 142 ->GetMainFrame() | |
| 143 ->GetRenderViewHost() | |
| 144 ->GetWidget() | |
| 145 ->GetView(); | |
| 146 } | |
| 147 return static_cast<RenderWidgetHostViewAndroid*>(rwhv); | |
| 148 } | |
| 149 | |
| 150 RenderWidgetHostConnector::RenderWidgetHostConnector(WebContents* web_contents) | |
| 151 : render_widget_observer_(new Observer(web_contents, this)) {} | |
| 152 | |
| 153 RenderWidgetHostConnector::~RenderWidgetHostConnector() {} | |
| 154 | |
| 155 RenderWidgetHostViewAndroid* RenderWidgetHostConnector::GetMainRWHVAForTesting() | |
| 156 const { | |
| 157 return render_widget_observer_->main_rwhva(); | |
| 158 } | |
| 159 | |
| 160 RenderWidgetHostViewAndroid* | |
| 161 RenderWidgetHostConnector::GetInterstitialRWHVAForTesting() const { | |
| 162 return render_widget_observer_->interstitial_rwhva(); | |
| 163 } | |
| 164 | |
| 165 } // namespace content | |
| OLD | NEW |