Skip to content
This repository was archived by the owner on Apr 3, 2020. It is now read-only.

Commit 354a041

Browse files
committed
[Android] Support third part media player on Crosswalk
A requirement from an important customer who want to forward web resources with proxy on Crosswalk, but android system MediaPlayer can't set a proxy with a standard API. The ExoMediaPlayer is playing videos and music is a popular activity on Android devices, and it can be configured with proxy. https://developer.android.com/guide/topics/media/exoplayer.html BUG=XWALK-6770
1 parent ebd7685 commit 354a041

File tree

6 files changed

+308
-4
lines changed

6 files changed

+308
-4
lines changed

runtime/android/core_internal/src/org/xwalk/core/internal/XWalkContent.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ public XWalkContent(Context context, String animatable, XWalkViewInternal xwView
149149
mGeolocationPermissions = new XWalkGeolocationPermissions(sharedPreferences);
150150

151151
MediaPlayerBridge.setResourceLoadingFilter(
152-
new XWalkMediaPlayerResourceLoadingFilter());
152+
new XWalkMediaPlayerResourceLoadingFilter(mContentsClientBridge));
153153

154154
setNativeContent(nativeInit(), animatable);
155155

@@ -389,6 +389,11 @@ public void setXWalkWebChromeClient(XWalkWebChromeClient client) {
389389
mContentsClientBridge.setXWalkWebChromeClient(client);
390390
}
391391

392+
public void setXWalkMediaPlayer(XWalkMediaPlayerInternal mediaPlayer) {
393+
if (mNativeContent == 0) return;
394+
mContentsClientBridge.setXWalkMediaPlayer(mediaPlayer);
395+
}
396+
392397
public XWalkWebChromeClient getXWalkWebChromeClient() {
393398
if (mNativeContent == 0) return null;
394399
return mContentsClientBridge.getXWalkWebChromeClient();

runtime/android/core_internal/src/org/xwalk/core/internal/XWalkContentsClientBridge.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ class XWalkContentsClientBridge extends XWalkContentsClient
7171
private XWalkNavigationHandler mNavigationHandler;
7272
private XWalkNotificationService mNotificationService;
7373
private Handler mUiThreadHandler;
74+
private XWalkMediaPlayerInternal mXWalkMediaPlayerInternal;
7475

7576
/** State recording variables */
7677
// For fullscreen state.
@@ -164,6 +165,13 @@ public void setResourceClient(XWalkResourceClientInternal client) {
164165
mXWalkResourceClient = new XWalkResourceClientInternal(mXWalkView);
165166
}
166167

168+
public void setXWalkMediaPlayer(XWalkMediaPlayerInternal mediaPlayer) {
169+
mXWalkMediaPlayerInternal = mediaPlayer;
170+
}
171+
172+
public XWalkMediaPlayerInternal getExternalMediaPlayer() {
173+
return mXWalkMediaPlayerInternal;
174+
}
167175

168176
public void setXWalkWebChromeClient(XWalkWebChromeClient client) {
169177
// If it's null, use Crosswalk implementation.
Lines changed: 267 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,267 @@
1+
// Copyright (c) 2016 Intel Corporation. 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+
package org.xwalk.core.internal;
6+
7+
import android.content.Context;
8+
import android.media.MediaPlayer.OnBufferingUpdateListener;
9+
import android.media.MediaPlayer.OnCompletionListener;
10+
import android.media.MediaPlayer.OnErrorListener;
11+
import android.media.MediaPlayer.OnPreparedListener;
12+
import android.media.MediaPlayer.OnSeekCompleteListener;
13+
import android.media.MediaPlayer.OnVideoSizeChangedListener;
14+
import android.media.MediaPlayer.TrackInfo;
15+
import android.net.Uri;
16+
import android.util.Log;
17+
import android.view.Surface;
18+
19+
import java.io.FileDescriptor;
20+
import java.util.HashMap;
21+
import java.util.Map;
22+
23+
import org.chromium.media.ExternalMediaPlayer;
24+
25+
@XWalkAPI(createExternally = true)
26+
public class XWalkMediaPlayerInternal extends ExternalMediaPlayer {
27+
private final static String TAG = "XWalkMediaPlayerInternal";
28+
29+
private void unsupported() {
30+
Log.e(TAG, "ERROR: The function must be implemented");
31+
throw new UnsupportedOperationException();
32+
}
33+
34+
/**
35+
* Sets the Surface to be used as the sink for the video portion of the media.
36+
* @param surface the Surface to be used for the video portion of the media.
37+
* @since 7.0
38+
*/
39+
@XWalkAPI
40+
public void setSurface(Surface surface) {
41+
unsupported();
42+
}
43+
44+
/**
45+
* Sets the data source as a content Uri.
46+
* @param context the Context to use when resolving the Uri.
47+
* @param uri the Content URI of the data you want to play.
48+
* @param headers the headers to be sent together with the request for the data.
49+
* @since 7.0
50+
*/
51+
@XWalkAPI
52+
public void setDataSource(Context context, Uri uri, Map<String, String> headers) {
53+
unsupported();
54+
}
55+
56+
/**
57+
* Sets the data source (FileDescriptor) to use.
58+
* @param fd the FileDescriptor for the file you want to play.
59+
* @param offset the offset into the file where the data to be played starts, in bytes.
60+
* @param length the length in bytes of the data to be played.
61+
* @since 7.0
62+
*/
63+
@XWalkAPI
64+
public void setDataSource(FileDescriptor fd, long offset, long length) {
65+
unsupported();
66+
}
67+
68+
/**
69+
* Sets the data source as a content Uri.
70+
* @param context the Context to use when resolving the Uri.
71+
* @param uri the Content URI of the data you want to play.
72+
* @since 7.0
73+
*/
74+
@XWalkAPI
75+
public void setDataSource(Context context, Uri uri) {
76+
unsupported();
77+
}
78+
79+
/**
80+
* Prepares the player for playback, asynchronously.
81+
* @since 7.0
82+
*/
83+
@XWalkAPI
84+
public void prepareAsync() {
85+
unsupported();
86+
}
87+
88+
/**
89+
* Checks whether the MediaPlayer is playing.
90+
* @return true if currently playing, false otherwise.
91+
* @since 7.0
92+
*/
93+
@XWalkAPI
94+
public boolean isPlaying() {
95+
unsupported();
96+
return false;
97+
}
98+
99+
/**
100+
* Returns the width of the video.
101+
* @return the width of the video, or 0 if there is no video.
102+
* @since 7.0
103+
*/
104+
@XWalkAPI
105+
public int getVideoWidth() {
106+
unsupported();
107+
return 0;
108+
}
109+
110+
/**
111+
* Returns the height of the video.
112+
* @return the height of the video, or 0 if there is no video.
113+
* @since 7.0
114+
*/
115+
@XWalkAPI
116+
public int getVideoHeight() {
117+
unsupported();
118+
return 0;
119+
}
120+
121+
/**
122+
* Gets the current playback position.
123+
* @return the current position in milliseconds.
124+
* @since 7.0
125+
*/
126+
@XWalkAPI
127+
public int getCurrentPosition() {
128+
unsupported();
129+
return 0;
130+
}
131+
132+
/**
133+
* Gets the duration of the file.
134+
* @return the duration in milliseconds, if no duration is
135+
* available (for example, if streaming live content), -1 is returned.
136+
* @since 7.0
137+
*/
138+
@XWalkAPI
139+
public int getDuration() {
140+
unsupported();
141+
return 0;
142+
}
143+
144+
/**
145+
* Releases resources associated with this MediaPlayer object.
146+
* @since 7.0
147+
*/
148+
@XWalkAPI
149+
public void release() {
150+
unsupported();
151+
}
152+
153+
/**
154+
* Sets the volume on this player.
155+
* @param volume1 left volume scalar.
156+
* @param volume2 right volume scalar.
157+
* @since 7.0
158+
*/
159+
@XWalkAPI
160+
public void setVolume(float volume1, float volume2) {
161+
unsupported();
162+
}
163+
164+
/**
165+
* Starts or resumes playback. If playback had previously been paused,
166+
* playback will continue from where it was paused. If playback had been stopped,
167+
* or never started before, playback will start at the beginning.
168+
* @since 7.0
169+
*/
170+
@XWalkAPI
171+
public void start() {
172+
unsupported();
173+
}
174+
175+
/**
176+
* Pauses playback. Call {@link XWalkMediaPlayerInternal#start()} to resume.
177+
* @since 7.0
178+
*/
179+
@XWalkAPI
180+
public void pause() {
181+
unsupported();
182+
}
183+
184+
/**
185+
* Seeks to specified time position.
186+
* @param msec the offset in milliseconds from the start to seek to.
187+
* @since 7.0
188+
*/
189+
@XWalkAPI
190+
public void seekTo(int msec) {
191+
unsupported();
192+
}
193+
194+
/**
195+
* Returns an array of track information.
196+
* @return array of track info.
197+
* @since 7.0
198+
*/
199+
@XWalkAPI
200+
public TrackInfo[] getTrackInfo() {
201+
unsupported();
202+
return null;
203+
}
204+
205+
/**
206+
* Register a callback to be invoked when the status of a network stream's
207+
* buffer has changed.
208+
* @param listener the callback that will be run.
209+
* @since 7.0
210+
*/
211+
@XWalkAPI
212+
public void setOnBufferingUpdateListener(OnBufferingUpdateListener listener) {
213+
unsupported();
214+
}
215+
216+
/**
217+
* Register a callback to be invoked when the end of a media source has
218+
* been reached during playback.
219+
* @param listener the callback that will be run.
220+
* @since 7.0
221+
*/
222+
@XWalkAPI
223+
public void setOnCompletionListener(OnCompletionListener listener) {
224+
unsupported();
225+
}
226+
227+
/**
228+
* Register a callback to be invoked when an error has happened during
229+
* an asynchronous operation.
230+
* @param listener the callback that will be run.
231+
* @since 7.0
232+
*/
233+
@XWalkAPI
234+
public void setOnErrorListener(OnErrorListener listener) {
235+
unsupported();
236+
}
237+
238+
/**
239+
* Register a callback to be invoked when the media source is ready for playback.
240+
* @param listener the callback that will be run.
241+
* @since 7.0
242+
*/
243+
@XWalkAPI
244+
public void setOnPreparedListener(OnPreparedListener listener) {
245+
unsupported();
246+
}
247+
248+
/**
249+
* Register a callback to be invoked when a seek operation has been completed.
250+
* @param listener the callback that will be run.
251+
* @since 7.0
252+
*/
253+
@XWalkAPI
254+
public void setOnSeekCompleteListener(OnSeekCompleteListener listener) {
255+
unsupported();
256+
}
257+
258+
/**
259+
* Register a callback to be invoked when the video size is known or updated.
260+
* @param listener the callback that will be run.
261+
* @since 7.0
262+
*/
263+
@XWalkAPI
264+
public void setOnVideoSizeChangedListener(OnVideoSizeChangedListener listener) {
265+
unsupported();
266+
}
267+
}

runtime/android/core_internal/src/org/xwalk/core/internal/XWalkMediaPlayerResourceLoadingFilter.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66

77
import android.content.Context;
88
import android.content.res.AssetFileDescriptor;
9-
import android.media.MediaPlayer;
109
import android.net.Uri;
1110

11+
import org.chromium.media.ExternalMediaPlayer;
1212
import org.chromium.media.MediaPlayerBridge;
1313

1414
import java.io.File;
@@ -22,8 +22,14 @@
2222

2323
class XWalkMediaPlayerResourceLoadingFilter extends
2424
MediaPlayerBridge.ResourceLoadingFilter {
25+
private XWalkContentsClientBridge mContentsClientBridge;
26+
27+
XWalkMediaPlayerResourceLoadingFilter(XWalkContentsClientBridge clientBridge) {
28+
mContentsClientBridge = clientBridge;
29+
}
30+
2531
@Override
26-
public boolean shouldOverrideResourceLoading(MediaPlayer mediaPlayer,
32+
public boolean shouldOverrideResourceLoading(ExternalMediaPlayer mediaPlayer,
2733
Context context, Uri uri) {
2834
String scheme = uri.getScheme();
2935
if (scheme == null) return false;
@@ -39,10 +45,14 @@ public boolean shouldOverrideResourceLoading(MediaPlayer mediaPlayer,
3945
context.getAssets().openFd(AndroidProtocolHandler.getAssetPath(uri));
4046
mediaPlayer.setDataSource(
4147
afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
42-
4348
return true;
4449
} catch (Exception e) {
4550
return false;
4651
}
4752
}
53+
54+
@Override
55+
public ExternalMediaPlayer getExternalMediaPlayer() {
56+
return mContentsClientBridge.getExternalMediaPlayer();
57+
}
4858
}

runtime/android/core_internal/src/org/xwalk/core/internal/XWalkViewInternal.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1022,6 +1022,19 @@ public void setResourceClient(XWalkResourceClientInternal client) {
10221022
mContent.setResourceClient(client);
10231023
}
10241024

1025+
/**
1026+
* Support third party MediaPlayer in Crosswalk with implementing the api
1027+
* from XWalkMediaPlayerInternal.
1028+
* @param mediaPlayer the XWalkMediaPlayerInternal implemented by customers.
1029+
* @since 7.0
1030+
*/
1031+
@XWalkAPI(reservable = true)
1032+
public void setXWalkMediaPlayer(XWalkMediaPlayerInternal mediaPlayer) {
1033+
if (mContent == null) return;
1034+
checkThreadSafety();
1035+
mContent.setXWalkMediaPlayer(mediaPlayer);
1036+
}
1037+
10251038
/**
10261039
* Set Background color of the view
10271040
*/

tools/reflection_generator/reflection_generator.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
'XWalkHttpAuthInternal',
4040
'XWalkJavascriptResultHandlerInternal',
4141
'XWalkJavascriptResultInternal',
42+
'XWalkMediaPlayerInternal',
4243
'XWalkNativeExtensionLoaderInternal',
4344
'XWalkNavigationHistoryInternal',
4445
'XWalkNavigationItemInternal',

0 commit comments

Comments
 (0)