/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsObserverProxy.java

http://github.com/chromium/chromium · Java · 308 lines · 241 code · 37 blank · 30 comment · 31 complexity · 303d3eb2eb5b76eb288627a5b83d6d9a MD5 · raw file

  1. // Copyright 2015 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. package org.chromium.content.browser.webcontents;
  5. import org.chromium.base.ObserverList;
  6. import org.chromium.base.ObserverList.RewindableIterator;
  7. import org.chromium.base.ThreadUtils;
  8. import org.chromium.base.annotations.CalledByNative;
  9. import org.chromium.base.annotations.JNINamespace;
  10. import org.chromium.base.annotations.NativeMethods;
  11. import org.chromium.content_public.browser.NavigationHandle;
  12. import org.chromium.content_public.browser.WebContentsObserver;
  13. /**
  14. * Serves as a compound observer proxy for dispatching WebContentsObserver callbacks,
  15. * avoiding redundant JNI-related work when there are multiple Java-based observers.
  16. */
  17. @JNINamespace("content")
  18. class WebContentsObserverProxy extends WebContentsObserver {
  19. private long mNativeWebContentsObserverProxy;
  20. private final ObserverList<WebContentsObserver> mObservers;
  21. private final RewindableIterator<WebContentsObserver> mObserversIterator;
  22. /**
  23. * Constructs a new WebContentsObserverProxy for a given WebContents
  24. * instance. A native WebContentsObserver instance will be created, which
  25. * will observe the native counterpart to the provided WebContents.
  26. *
  27. * @param webContents The WebContents instance to observe.
  28. */
  29. public WebContentsObserverProxy(WebContentsImpl webContents) {
  30. ThreadUtils.assertOnUiThread();
  31. mNativeWebContentsObserverProxy =
  32. WebContentsObserverProxyJni.get().init(WebContentsObserverProxy.this, webContents);
  33. mObservers = new ObserverList<WebContentsObserver>();
  34. mObserversIterator = mObservers.rewindableIterator();
  35. }
  36. /**
  37. * Add an observer to the list of proxied observers.
  38. * @param observer The WebContentsObserver instance to add.
  39. */
  40. void addObserver(WebContentsObserver observer) {
  41. assert mNativeWebContentsObserverProxy != 0;
  42. mObservers.addObserver(observer);
  43. }
  44. /**
  45. * Remove an observer from the list of proxied observers.
  46. * @param observer The WebContentsObserver instance to remove.
  47. */
  48. void removeObserver(WebContentsObserver observer) {
  49. mObservers.removeObserver(observer);
  50. }
  51. /**
  52. * @return Whether there are any active, proxied observers.
  53. */
  54. boolean hasObservers() {
  55. return !mObservers.isEmpty();
  56. }
  57. @Override
  58. @CalledByNative
  59. public void renderViewReady() {
  60. for (mObserversIterator.rewind(); mObserversIterator.hasNext();) {
  61. mObserversIterator.next().renderViewReady();
  62. }
  63. }
  64. @Override
  65. @CalledByNative
  66. public void renderProcessGone(boolean wasOomProtected) {
  67. for (mObserversIterator.rewind(); mObserversIterator.hasNext();) {
  68. mObserversIterator.next().renderProcessGone(wasOomProtected);
  69. }
  70. }
  71. @Override
  72. @CalledByNative
  73. public void didStartNavigation(NavigationHandle navigation) {
  74. for (mObserversIterator.rewind(); mObserversIterator.hasNext();) {
  75. mObserversIterator.next().didStartNavigation(navigation);
  76. }
  77. }
  78. @Override
  79. @CalledByNative
  80. public void didRedirectNavigation(NavigationHandle navigation) {
  81. for (mObserversIterator.rewind(); mObserversIterator.hasNext();) {
  82. mObserversIterator.next().didRedirectNavigation(navigation);
  83. }
  84. }
  85. @Override
  86. @CalledByNative
  87. public void didFinishNavigation(NavigationHandle navigation) {
  88. for (mObserversIterator.rewind(); mObserversIterator.hasNext();) {
  89. mObserversIterator.next().didFinishNavigation(navigation);
  90. }
  91. }
  92. @Override
  93. @CalledByNative
  94. public void didStartLoading(String url) {
  95. for (mObserversIterator.rewind(); mObserversIterator.hasNext();) {
  96. mObserversIterator.next().didStartLoading(url);
  97. }
  98. }
  99. @Override
  100. @CalledByNative
  101. public void didStopLoading(String url) {
  102. for (mObserversIterator.rewind(); mObserversIterator.hasNext();) {
  103. mObserversIterator.next().didStopLoading(url);
  104. }
  105. }
  106. @Override
  107. @CalledByNative
  108. public void loadProgressChanged(float progress) {
  109. for (mObserversIterator.rewind(); mObserversIterator.hasNext();) {
  110. mObserversIterator.next().loadProgressChanged(progress);
  111. }
  112. }
  113. @Override
  114. @CalledByNative
  115. public void didChangeVisibleSecurityState() {
  116. for (mObserversIterator.rewind(); mObserversIterator.hasNext();) {
  117. mObserversIterator.next().didChangeVisibleSecurityState();
  118. }
  119. }
  120. @Override
  121. @CalledByNative
  122. public void didFailLoad(boolean isMainFrame, int errorCode, String failingUrl) {
  123. for (mObserversIterator.rewind(); mObserversIterator.hasNext();) {
  124. mObserversIterator.next().didFailLoad(isMainFrame, errorCode, failingUrl);
  125. }
  126. }
  127. @Override
  128. @CalledByNative
  129. public void didFirstVisuallyNonEmptyPaint() {
  130. for (mObserversIterator.rewind(); mObserversIterator.hasNext();) {
  131. mObserversIterator.next().didFirstVisuallyNonEmptyPaint();
  132. }
  133. }
  134. @Override
  135. @CalledByNative
  136. public void wasShown() {
  137. for (mObserversIterator.rewind(); mObserversIterator.hasNext();) {
  138. mObserversIterator.next().wasShown();
  139. }
  140. }
  141. @Override
  142. @CalledByNative
  143. public void wasHidden() {
  144. for (mObserversIterator.rewind(); mObserversIterator.hasNext();) {
  145. mObserversIterator.next().wasHidden();
  146. }
  147. }
  148. @Override
  149. @CalledByNative
  150. public void titleWasSet(String title) {
  151. for (mObserversIterator.rewind(); mObserversIterator.hasNext();) {
  152. mObserversIterator.next().titleWasSet(title);
  153. }
  154. }
  155. @Override
  156. @CalledByNative
  157. public void documentAvailableInMainFrame() {
  158. for (mObserversIterator.rewind(); mObserversIterator.hasNext();) {
  159. mObserversIterator.next().documentAvailableInMainFrame();
  160. }
  161. }
  162. @Override
  163. @CalledByNative
  164. public void didFinishLoad(long frameId, String validatedUrl, boolean isMainFrame) {
  165. for (mObserversIterator.rewind(); mObserversIterator.hasNext();) {
  166. mObserversIterator.next().didFinishLoad(frameId, validatedUrl, isMainFrame);
  167. }
  168. }
  169. @Override
  170. @CalledByNative
  171. public void documentLoadedInFrame(long frameId, boolean isMainFrame) {
  172. for (mObserversIterator.rewind(); mObserversIterator.hasNext();) {
  173. mObserversIterator.next().documentLoadedInFrame(frameId, isMainFrame);
  174. }
  175. }
  176. @Override
  177. @CalledByNative
  178. public void navigationEntryCommitted() {
  179. for (mObserversIterator.rewind(); mObserversIterator.hasNext();) {
  180. mObserversIterator.next().navigationEntryCommitted();
  181. }
  182. }
  183. @Override
  184. @CalledByNative
  185. public void navigationEntriesDeleted() {
  186. for (mObserversIterator.rewind(); mObserversIterator.hasNext();) {
  187. mObserversIterator.next().navigationEntriesDeleted();
  188. }
  189. }
  190. @Override
  191. @CalledByNative
  192. public void navigationEntriesChanged() {
  193. for (mObserversIterator.rewind(); mObserversIterator.hasNext();) {
  194. mObserversIterator.next().navigationEntriesChanged();
  195. }
  196. }
  197. @Override
  198. @CalledByNative
  199. public void didAttachInterstitialPage() {
  200. for (mObserversIterator.rewind(); mObserversIterator.hasNext();) {
  201. mObserversIterator.next().didAttachInterstitialPage();
  202. }
  203. }
  204. @Override
  205. @CalledByNative
  206. public void didDetachInterstitialPage() {
  207. for (mObserversIterator.rewind(); mObserversIterator.hasNext();) {
  208. mObserversIterator.next().didDetachInterstitialPage();
  209. }
  210. }
  211. @Override
  212. @CalledByNative
  213. public void didChangeThemeColor() {
  214. for (mObserversIterator.rewind(); mObserversIterator.hasNext();) {
  215. mObserversIterator.next().didChangeThemeColor();
  216. }
  217. }
  218. @Override
  219. @CalledByNative
  220. public void hasEffectivelyFullscreenVideoChange(boolean isFullscreen) {
  221. for (mObserversIterator.rewind(); mObserversIterator.hasNext();) {
  222. mObserversIterator.next().hasEffectivelyFullscreenVideoChange(isFullscreen);
  223. }
  224. }
  225. @Override
  226. @CalledByNative
  227. public void viewportFitChanged(@WebContentsObserver.ViewportFitType int value) {
  228. for (mObserversIterator.rewind(); mObserversIterator.hasNext();) {
  229. mObserversIterator.next().viewportFitChanged(value);
  230. }
  231. }
  232. @Override
  233. @CalledByNative
  234. public void onWebContentsFocused() {
  235. for (mObserversIterator.rewind(); mObserversIterator.hasNext();) {
  236. mObserversIterator.next().onWebContentsFocused();
  237. }
  238. }
  239. @Override
  240. @CalledByNative
  241. public void onWebContentsLostFocus() {
  242. for (mObserversIterator.rewind(); mObserversIterator.hasNext();) {
  243. mObserversIterator.next().onWebContentsLostFocus();
  244. }
  245. }
  246. @Override
  247. @CalledByNative
  248. public void destroy() {
  249. // Super destruction semantics (removing the observer from the
  250. // Java-based WebContents) are quite different, so we explicitly avoid
  251. // calling it here.
  252. ThreadUtils.assertOnUiThread();
  253. for (mObserversIterator.rewind(); mObserversIterator.hasNext();) {
  254. mObserversIterator.next().destroy();
  255. }
  256. // All observer destroy() implementations should result in their removal
  257. // from the proxy.
  258. assert mObservers.isEmpty();
  259. mObservers.clear();
  260. if (mNativeWebContentsObserverProxy != 0) {
  261. WebContentsObserverProxyJni.get().destroy(
  262. mNativeWebContentsObserverProxy, WebContentsObserverProxy.this);
  263. mNativeWebContentsObserverProxy = 0;
  264. }
  265. }
  266. @NativeMethods
  267. interface Natives {
  268. long init(WebContentsObserverProxy caller, WebContentsImpl webContents);
  269. void destroy(long nativeWebContentsObserverProxy, WebContentsObserverProxy caller);
  270. }
  271. }