OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 package org.chromium.android_webview; | 5 package org.chromium.android_webview; |
6 | 6 |
7 import android.content.Context; | 7 import android.content.Context; |
8 import android.graphics.Canvas; | 8 import android.graphics.Canvas; |
9 import android.view.Surface; | 9 import android.view.Surface; |
10 import android.view.SurfaceHolder; | 10 import android.view.SurfaceHolder; |
11 import android.view.SurfaceView; | 11 import android.view.SurfaceView; |
12 import android.view.ViewGroup; | 12 import android.view.ViewGroup; |
13 | 13 |
| 14 import com.google.common.annotations.VisibleForTesting; |
| 15 |
14 import org.chromium.base.CalledByNative; | 16 import org.chromium.base.CalledByNative; |
15 import org.chromium.base.JNINamespace; | 17 import org.chromium.base.JNINamespace; |
16 import org.chromium.content.browser.ContentViewCore; | 18 import org.chromium.content.browser.ContentViewCore; |
17 import org.chromium.content.browser.RenderCoordinates; | 19 import org.chromium.content.browser.RenderCoordinates; |
18 | 20 |
19 import java.lang.ref.WeakReference; | 21 import java.lang.ref.WeakReference; |
20 | 22 |
21 /** | 23 /** |
22 * This is a container for external video surfaces. | 24 * This is a container for external video surfaces. |
23 * The object is owned by the native peer and it is owned by WebContents. | 25 * The object is owned by the native peer and it is owned by WebContents. |
24 * | 26 * |
25 * The expected behavior of the media player on the video hole punching is as fo
llows. | 27 * The expected behavior of the media player on the video hole punching is as fo
llows. |
26 * 1) If it requests the surface, it will call requestExternalVideoSurface(). | 28 * 1) If it requests the surface, it will call requestExternalVideoSurface(). |
27 * When the resolution of the video is changed, it'll call requestExternalVid
eoSurface(). | 29 * When the resolution of the video is changed, it'll call requestExternalVid
eoSurface(). |
28 * 2) Whenever the size or the position of the video element is changed, it'll n
otify through | 30 * 2) Whenever the size or the position of the video element is changed, it'll n
otify through |
29 * onExternalVideoSurfacePositionChanged(). | 31 * onExternalVideoSurfacePositionChanged(). |
30 * 3) Whenever the page that contains the video element is scrolled or zoomed, | 32 * 3) Whenever the page that contains the video element is scrolled or zoomed, |
31 * onFrameInfoUpdated() will be called. | 33 * onFrameInfoUpdated() will be called. |
32 * 4) Usually steps 1) ~ 3) are repeated during the playback. | 34 * 4) Usually steps 1) ~ 3) are repeated during the playback. |
33 * 5) If the player no longer needs the surface any more, it'll call | 35 * 5) If the player no longer needs the surface any more, it'll call |
34 * releaseExternalVideoSurface(). | 36 * releaseExternalVideoSurface(). |
35 * | 37 * |
36 * Please contact ycheo@chromium.org or wonsik@chromium.org if you have any | 38 * Please contact ycheo@chromium.org or wonsik@chromium.org if you have any |
37 * questions or issues for this class. | 39 * questions or issues for this class. |
38 */ | 40 */ |
39 @JNINamespace("android_webview") | 41 @JNINamespace("android_webview") |
40 public class ExternalVideoSurfaceContainer implements SurfaceHolder.Callback { | 42 public class ExternalVideoSurfaceContainer implements SurfaceHolder.Callback { |
41 private static final int INVALID_PLAYER_ID = -1; | 43 protected static final int INVALID_PLAYER_ID = -1; |
42 | 44 |
43 // Because WebView does hole-punching by itself, instead, the hole-punching
logic | 45 // Because WebView does hole-punching by itself, instead, the hole-punching
logic |
44 // in SurfaceView can clear out some web elements like media control or subt
itle. | 46 // in SurfaceView can clear out some web elements like media control or subt
itle. |
45 // So we need to disable its hole-punching logic. | 47 // So we need to disable its hole-punching logic. |
46 private static class NoPunchingSurfaceView extends SurfaceView { | 48 private static class NoPunchingSurfaceView extends SurfaceView { |
47 public NoPunchingSurfaceView(Context context) { | 49 public NoPunchingSurfaceView(Context context) { |
48 super(context); | 50 super(context); |
49 } | 51 } |
50 // SurfaceView.dispatchDraw implementation punches a hole in the view hi
erarchy. | 52 // SurfaceView.dispatchDraw implementation punches a hole in the view hi
erarchy. |
51 // Disable this by making this a no-op. | 53 // Disable this by making this a no-op. |
(...skipping 19 matching lines...) Expand all Loading... |
71 private float mTop; | 73 private float mTop; |
72 private float mRight; | 74 private float mRight; |
73 private float mBottom; | 75 private float mBottom; |
74 | 76 |
75 // The physical location/size of the external video surface in pixels. | 77 // The physical location/size of the external video surface in pixels. |
76 private int mX; | 78 private int mX; |
77 private int mY; | 79 private int mY; |
78 private int mWidth; | 80 private int mWidth; |
79 private int mHeight; | 81 private int mHeight; |
80 | 82 |
| 83 /** |
| 84 * Factory class to facilitate dependency injection. |
| 85 */ |
| 86 public static class Factory { |
| 87 public ExternalVideoSurfaceContainer create( |
| 88 int nativeExternalVideoSurfaceContainer, ContentViewCore content
ViewCore) { |
| 89 return new ExternalVideoSurfaceContainer( |
| 90 nativeExternalVideoSurfaceContainer, contentViewCore); |
| 91 } |
| 92 } |
| 93 private static Factory sFactory = new Factory(); |
| 94 |
| 95 @VisibleForTesting |
| 96 public static void setFactory(Factory factory) { |
| 97 sFactory = factory; |
| 98 } |
| 99 |
81 @CalledByNative | 100 @CalledByNative |
82 private static ExternalVideoSurfaceContainer create( | 101 private static ExternalVideoSurfaceContainer create( |
83 int nativeExternalVideoSurfaceContainer, ContentViewCore contentView
Core) { | 102 int nativeExternalVideoSurfaceContainer, ContentViewCore contentView
Core) { |
84 return new ExternalVideoSurfaceContainer( | 103 return sFactory.create(nativeExternalVideoSurfaceContainer, contentViewC
ore); |
85 nativeExternalVideoSurfaceContainer, contentViewCore); | |
86 } | 104 } |
87 | 105 |
88 private ExternalVideoSurfaceContainer( | 106 protected ExternalVideoSurfaceContainer( |
89 int nativeExternalVideoSurfaceContainer, ContentViewCore contentView
Core) { | 107 int nativeExternalVideoSurfaceContainer, ContentViewCore contentView
Core) { |
90 assert contentViewCore != null; | 108 assert contentViewCore != null; |
91 mNativeExternalVideoSurfaceContainer = nativeExternalVideoSurfaceContain
er; | 109 mNativeExternalVideoSurfaceContainer = nativeExternalVideoSurfaceContain
er; |
92 mContentViewCore = contentViewCore; | 110 mContentViewCore = contentViewCore; |
93 initializeCurrentPositionOfSurfaceView(); | 111 initializeCurrentPositionOfSurfaceView(); |
94 } | 112 } |
95 | 113 |
96 /** | 114 /** |
97 * Called when a media player wants to request an external video surface. | 115 * Called when a media player wants to request an external video surface. |
98 * @param playerId The ID of the media player. | 116 * @param playerId The ID of the media player. |
99 */ | 117 */ |
100 @CalledByNative | 118 @CalledByNative |
101 private void requestExternalVideoSurface(int playerId) { | 119 protected void requestExternalVideoSurface(int playerId) { |
102 if (mPlayerId == playerId) return; | 120 if (mPlayerId == playerId) return; |
103 | 121 |
104 if (mPlayerId == INVALID_PLAYER_ID) { | 122 if (mPlayerId == INVALID_PLAYER_ID) { |
105 setActiveContainer(this); | 123 setActiveContainer(this); |
106 } | 124 } |
107 | 125 |
108 mPlayerId = playerId; | 126 mPlayerId = playerId; |
109 initializeCurrentPositionOfSurfaceView(); | 127 initializeCurrentPositionOfSurfaceView(); |
110 | 128 |
111 createSurfaceView(); | 129 createSurfaceView(); |
112 } | 130 } |
113 | 131 |
114 /** | 132 /** |
115 * Called when a media player wants to release an external video surface. | 133 * Called when a media player wants to release an external video surface. |
116 * @param playerId The ID of the media player. | 134 * @param playerId The ID of the media player. |
117 */ | 135 */ |
118 @CalledByNative | 136 @CalledByNative |
119 private void releaseExternalVideoSurface(int playerId) { | 137 protected void releaseExternalVideoSurface(int playerId) { |
120 if (mPlayerId != playerId) return; | 138 if (mPlayerId != playerId) return; |
121 | 139 |
122 releaseIfActiveContainer(this); | 140 releaseIfActiveContainer(this); |
123 | 141 |
124 mPlayerId = INVALID_PLAYER_ID; | 142 mPlayerId = INVALID_PLAYER_ID; |
125 } | 143 } |
126 | 144 |
127 @CalledByNative | 145 @CalledByNative |
128 private void destroy() { | 146 protected void destroy() { |
129 releaseExternalVideoSurface(mPlayerId); | 147 releaseExternalVideoSurface(mPlayerId); |
130 } | 148 } |
131 | 149 |
132 private void initializeCurrentPositionOfSurfaceView() { | 150 private void initializeCurrentPositionOfSurfaceView() { |
133 mX = Integer.MIN_VALUE; | 151 mX = Integer.MIN_VALUE; |
134 mY = Integer.MIN_VALUE; | 152 mY = Integer.MIN_VALUE; |
135 mWidth = 0; | 153 mWidth = 0; |
136 mHeight = 0; | 154 mHeight = 0; |
137 } | 155 } |
138 | 156 |
(...skipping 30 matching lines...) Expand all Loading... |
169 /** | 187 /** |
170 * Called when the position of the video element which uses the external | 188 * Called when the position of the video element which uses the external |
171 * video surface is changed. | 189 * video surface is changed. |
172 * @param playerId The ID of the media player. | 190 * @param playerId The ID of the media player. |
173 * @param left The absolute CSS X coordinate of the left side of the video e
lement. | 191 * @param left The absolute CSS X coordinate of the left side of the video e
lement. |
174 * @param top The absolute CSS Y coordinate of the top side of the video ele
ment. | 192 * @param top The absolute CSS Y coordinate of the top side of the video ele
ment. |
175 * @param right The absolute CSS X coordinate of the right side of the video
element. | 193 * @param right The absolute CSS X coordinate of the right side of the video
element. |
176 * @param bottom The absolute CSS Y coordinate of the bottom side of the vid
eo element. | 194 * @param bottom The absolute CSS Y coordinate of the bottom side of the vid
eo element. |
177 */ | 195 */ |
178 @CalledByNative | 196 @CalledByNative |
179 private void onExternalVideoSurfacePositionChanged( | 197 protected void onExternalVideoSurfacePositionChanged( |
180 int playerId, float left, float top, float right, float bottom) { | 198 int playerId, float left, float top, float right, float bottom) { |
181 if (mPlayerId != playerId) return; | 199 if (mPlayerId != playerId) return; |
182 | 200 |
183 mLeft = left; | 201 mLeft = left; |
184 mTop = top; | 202 mTop = top; |
185 mRight = right; | 203 mRight = right; |
186 mBottom = bottom; | 204 mBottom = bottom; |
187 | 205 |
188 layOutSurfaceView(); | 206 layOutSurfaceView(); |
189 } | 207 } |
190 | 208 |
191 /** | 209 /** |
192 * Called when the page that contains the video element is scrolled or zoome
d. | 210 * Called when the page that contains the video element is scrolled or zoome
d. |
193 */ | 211 */ |
194 @CalledByNative | 212 @CalledByNative |
195 private void onFrameInfoUpdated() { | 213 protected void onFrameInfoUpdated() { |
196 if (mPlayerId == INVALID_PLAYER_ID) return; | 214 if (mPlayerId == INVALID_PLAYER_ID) return; |
197 | 215 |
198 layOutSurfaceView(); | 216 layOutSurfaceView(); |
199 } | 217 } |
200 | 218 |
201 private void layOutSurfaceView() { | 219 private void layOutSurfaceView() { |
202 RenderCoordinates renderCoordinates = mContentViewCore.getRenderCoordina
tes(); | 220 RenderCoordinates renderCoordinates = mContentViewCore.getRenderCoordina
tes(); |
203 RenderCoordinates.NormalizedPoint topLeft = renderCoordinates.createNorm
alizedPoint(); | 221 RenderCoordinates.NormalizedPoint topLeft = renderCoordinates.createNorm
alizedPoint(); |
204 RenderCoordinates.NormalizedPoint bottomRight = renderCoordinates.create
NormalizedPoint(); | 222 RenderCoordinates.NormalizedPoint bottomRight = renderCoordinates.create
NormalizedPoint(); |
205 topLeft.setAbsoluteCss(mLeft, mTop); | 223 topLeft.setAbsoluteCss(mLeft, mTop); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
250 } | 268 } |
251 } | 269 } |
252 | 270 |
253 private native void nativeSurfaceCreated( | 271 private native void nativeSurfaceCreated( |
254 long nativeExternalVideoSurfaceContainerImpl, int playerId, Surface
surface); | 272 long nativeExternalVideoSurfaceContainerImpl, int playerId, Surface
surface); |
255 | 273 |
256 private native void nativeSurfaceDestroyed( | 274 private native void nativeSurfaceDestroyed( |
257 long nativeExternalVideoSurfaceContainerImpl, int playerId); | 275 long nativeExternalVideoSurfaceContainerImpl, int playerId); |
258 } | 276 } |
259 | 277 |
OLD | NEW |