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

Commit

Permalink
[Android] Support third part media player on Crosswalk
Browse files Browse the repository at this point in the history
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
  • Loading branch information
fujunwei committed Jun 27, 2016
1 parent 87feec5 commit 9baa6c1
Show file tree
Hide file tree
Showing 6 changed files with 300 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ public XWalkContent(Context context, String animatable, XWalkViewInternal xwView
mGeolocationPermissions = new XWalkGeolocationPermissions(sharedPreferences);

MediaPlayerBridge.setResourceLoadingFilter(
new XWalkMediaPlayerResourceLoadingFilter());
new XWalkMediaPlayerResourceLoadingFilter(mContentsClientBridge));

setNativeContent(nativeInit(), animatable);

Expand Down Expand Up @@ -379,6 +379,11 @@ public void setXWalkWebChromeClient(XWalkWebChromeClient client) {
mContentsClientBridge.setXWalkWebChromeClient(client);
}

public void setXWalkMediaPlayer(XWalkMediaPlayerInternal mediaPlayer) {
if (mNativeContent == 0) return;
mContentsClientBridge.setXWalkMediaPlayer(mediaPlayer);
}

public XWalkWebChromeClient getXWalkWebChromeClient() {
if (mNativeContent == 0) return null;
return mContentsClientBridge.getXWalkWebChromeClient();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ class XWalkContentsClientBridge extends XWalkContentsClient
private XWalkNavigationHandler mNavigationHandler;
private XWalkNotificationService mNotificationService;
private Handler mUiThreadHandler;
private XWalkMediaPlayerInternal mXWalkMediaPlayerInternal;

/** State recording variables */
// For fullscreen state.
Expand Down Expand Up @@ -163,6 +164,13 @@ public void setResourceClient(XWalkResourceClientInternal client) {
mXWalkResourceClient = new XWalkResourceClientInternal(mXWalkView);
}

public void setXWalkMediaPlayer(XWalkMediaPlayerInternal mediaPlayer) {
mXWalkMediaPlayerInternal = mediaPlayer;
}

public XWalkMediaPlayerInternal getExternalMediaPlayer() {
return mXWalkMediaPlayerInternal;
}

public void setXWalkWebChromeClient(XWalkWebChromeClient client) {
// If it's null, use Crosswalk implementation.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,253 @@
// Copyright (c) 2016 Intel Corporation. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package org.xwalk.core.internal;

import android.content.Context;
import android.media.MediaPlayer.OnBufferingUpdateListener;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.media.MediaPlayer.OnSeekCompleteListener;
import android.media.MediaPlayer.OnVideoSizeChangedListener;
import android.media.MediaPlayer.TrackInfo;
import android.net.Uri;
import android.util.Log;
import android.view.Surface;

import java.io.FileDescriptor;
import java.util.HashMap;
import java.util.Map;

import org.chromium.media.ExternalMediaPlayer;

@XWalkAPI(createExternally = true)
public class XWalkMediaPlayerInternal extends ExternalMediaPlayer {
private final static String TAG = "XWalkMediaPlayerInternal";

private void unsupported() {
Log.e(TAG, "ERROR: The function must be implemented");
throw new UnsupportedOperationException();
}

/**
* Sets the Surface to be used as the sink for the video portion of the media.
* @param surface the Surface to be used for the video portion of the media.
* @since 7.0
*/
@XWalkAPI
public void setSurface(Surface surface) {
unsupported();
}

/**
* Sets the data source as a content Uri.
* @param context the Context to use when resolving the Uri.
* @param uri the Content URI of the data you want to play.
* @param headers the headers to be sent together with the request for the data.
* @since 7.0
*/
@XWalkAPI
public void setDataSource(Context context, Uri uri, Map<String, String> headers) {
unsupported();
}

/**
* Sets the data source (FileDescriptor) to use.
* @param offset the offset into the file where the data to be played starts, in bytes.
* @param length the length in bytes of the data to be played.
* @since 7.0
*/
@XWalkAPI
public void setDataSource(FileDescriptor fd, long offset, long length) {
unsupported();
}

/**
* Sets the data source as a content Uri.
* @param context the Context to use when resolving the Uri.
* @param uri the Content URI of the data you want to play.
* @since 7.0
*/
@XWalkAPI
public void setDataSource(Context context, Uri uri) {
unsupported();
}

/**
* Prepares the player for playback, asynchronously.
* @since 7.0
*/
@XWalkAPI
public void prepareAsync() {
unsupported();
}

/**
* Checks whether the MediaPlayer is playing.
* @since 7.0
*/
@XWalkAPI
public boolean isPlaying() {
unsupported();
return false;
}

/**
* Returns the width of the video.
* @since 7.0
*/
@XWalkAPI
public int getVideoWidth() {
unsupported();
return 0;
}

/**
* Returns the height of the video.
* @since 7.0
*/
@XWalkAPI
public int getVideoHeight() {
unsupported();
return 0;
}

/**
* Gets the current playback position.
* @since 7.0
*/
@XWalkAPI
public int getCurrentPosition() {
unsupported();
return 0;
}

/**
* Gets the duration of the file.
* @since 7.0
*/
@XWalkAPI
public int getDuration() {
unsupported();
return 0;
}

/**
* Releases resources associated with this MediaPlayer object.
* @since 7.0
*/
@XWalkAPI
public void release() {
unsupported();
}

/**
* Sets the volume on this player.
* @since 7.0
*/
@XWalkAPI
public void setVolume(float volume1, float volume2) {
unsupported();
}

/**
* Starts or resumes playback. If playback had previously been paused,
* playback will continue from where it was paused. If playback had been stopped,
* or never started before, playback will start at the beginning.
* @since 7.0
*/
@XWalkAPI
public void start() {
unsupported();
}

/**
* Pauses playback. Call start() to resume.
* @since 7.0
*/
@XWalkAPI
public void pause() {
unsupported();
}

/**
* Seeks to specified time position.
* @since 7.0
*/
@XWalkAPI
public void seekTo(int msec) {
unsupported();
}

/**
* Returns an array of track information.
* @since 7.0
*/
@XWalkAPI
public TrackInfo[] getTrackInfo() {
unsupported();
return null;
}

/**
* Register a callback to be invoked when the status of a network stream's buffer has changed.
* @param listener the callback that will be run.
* @since 7.0
*/
@XWalkAPI
public void setOnBufferingUpdateListener(OnBufferingUpdateListener listener) {
unsupported();
}

/**
* Register a callback to be invoked when the end of a media source has been reached during playback.
* @param listener the callback that will be run.
* @since 7.0
*/
@XWalkAPI
public void setOnCompletionListener(OnCompletionListener listener) {
unsupported();
}

/**
* Register a callback to be invoked when an error has happened during an asynchronous operation.
* @param listener the callback that will be run.
* @since 7.0
*/
@XWalkAPI
public void setOnErrorListener(OnErrorListener listener) {
unsupported();
}

/**
* Register a callback to be invoked when the media source is ready for playback.
* @param listener the callback that will be run.
* @since 7.0
*/
@XWalkAPI
public void setOnPreparedListener(OnPreparedListener listener) {
unsupported();
}

/**
* Register a callback to be invoked when a seek operation has been completed.
* @param listener the callback that will be run.
* @since 7.0
*/
@XWalkAPI
public void setOnSeekCompleteListener(OnSeekCompleteListener listener) {
unsupported();
}

/**
* Register a callback to be invoked when the video size is known or updated.
* @param listener the callback that will be run.
* @since 7.0
*/
@XWalkAPI
public void setOnVideoSizeChangedListener(OnVideoSizeChangedListener listener) {
unsupported();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@

import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.media.MediaPlayer;
import android.net.Uri;

import org.chromium.media.ExternalMediaPlayer;
import org.chromium.media.MediaPlayerBridge;

import java.io.File;
Expand All @@ -22,8 +22,14 @@

class XWalkMediaPlayerResourceLoadingFilter extends
MediaPlayerBridge.ResourceLoadingFilter {
private XWalkContentsClientBridge mContentsClientBridge;

XWalkMediaPlayerResourceLoadingFilter(XWalkContentsClientBridge clientBridge) {
mContentsClientBridge = clientBridge;
}

@Override
public boolean shouldOverrideResourceLoading(MediaPlayer mediaPlayer,
public boolean shouldOverrideResourceLoading(ExternalMediaPlayer mediaPlayer,
Context context, Uri uri) {
String scheme = uri.getScheme();
if (scheme == null) return false;
Expand All @@ -39,10 +45,20 @@ public boolean shouldOverrideResourceLoading(MediaPlayer mediaPlayer,
context.getAssets().openFd(AndroidProtocolHandler.getAssetPath(uri));
mediaPlayer.setDataSource(
afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());

return true;
} catch (Exception e) {
return false;
}
}

@Override
public ExternalMediaPlayer getExternalMediaPlayer() {
ExternalMediaPlayer exMediaPlayer = mContentsClientBridge.getExternalMediaPlayer();

if (exMediaPlayer == null) {
exMediaPlayer = new ExternalMediaPlayer();
}

return exMediaPlayer;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -954,6 +954,19 @@ public void setResourceClient(XWalkResourceClientInternal client) {
mContent.setResourceClient(client);
}

/**
* Support third party MediaPlayer in Crosswalk with implementing the api
* from XWalkMediaPlayerInternal.
* @param mediaPlayer the XWalkMediaPlayerInternal implemented by customers.
* @since 7.0
*/
@XWalkAPI(reservable = true)
public void setXWalkMediaPlayer(XWalkMediaPlayerInternal mediaPlayer) {
if (mContent == null) return;
checkThreadSafety();
mContent.setXWalkMediaPlayer(mediaPlayer);
}

/**
* Set Background color of the view
*/
Expand Down
1 change: 1 addition & 0 deletions tools/reflection_generator/reflection_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
'XWalkWebResourceRequestHandlerInternal',
'XWalkWebResourceRequestInternal',
'XWalkWebResourceResponseInternal',
'XWalkMediaPlayerInternal',
]

REFLECTION_HERLPER = [
Expand Down

0 comments on commit 9baa6c1

Please sign in to comment.