Merge "Listen for HTTP proxy changes and propagate the information to the media" into jb-mr2-dev

This commit is contained in:
Andreas Huber
2013-06-03 15:44:16 +00:00
committed by Android (Google) Code Review
2 changed files with 139 additions and 3 deletions

View File

@@ -16,9 +16,14 @@
package android.media; package android.media;
import android.content.BroadcastReceiver;
import android.content.ContentResolver; import android.content.ContentResolver;
import android.content.Context; import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.AssetFileDescriptor; import android.content.res.AssetFileDescriptor;
import android.net.Proxy;
import android.net.ProxyProperties;
import android.net.Uri; import android.net.Uri;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
@@ -864,6 +869,7 @@ public class MediaPlayer
*/ */
public void setDataSource(Context context, Uri uri, Map<String, String> headers) public void setDataSource(Context context, Uri uri, Map<String, String> headers)
throws IOException, IllegalArgumentException, SecurityException, IllegalStateException { throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
disableProxyListener();
String scheme = uri.getScheme(); String scheme = uri.getScheme();
if(scheme == null || scheme.equals("file")) { if(scheme == null || scheme.equals("file")) {
@@ -896,8 +902,13 @@ public class MediaPlayer
} }
Log.d(TAG, "Couldn't open file on client side, trying server side"); Log.d(TAG, "Couldn't open file on client side, trying server side");
setDataSource(uri.toString(), headers); setDataSource(uri.toString(), headers);
return;
if (scheme.equalsIgnoreCase("http")
|| scheme.equalsIgnoreCase("https")) {
setupProxyListener(context);
}
} }
/** /**
@@ -948,6 +959,8 @@ public class MediaPlayer
private void setDataSource(String path, String[] keys, String[] values) private void setDataSource(String path, String[] keys, String[] values)
throws IOException, IllegalArgumentException, SecurityException, IllegalStateException { throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
disableProxyListener();
final Uri uri = Uri.parse(path); final Uri uri = Uri.parse(path);
if ("file".equals(uri.getScheme())) { if ("file".equals(uri.getScheme())) {
path = uri.getPath(); path = uri.getPath();
@@ -991,7 +1004,13 @@ public class MediaPlayer
* @param length the length in bytes of the data to be played * @param length the length in bytes of the data to be played
* @throws IllegalStateException if it is called in an invalid state * @throws IllegalStateException if it is called in an invalid state
*/ */
public native void setDataSource(FileDescriptor fd, long offset, long length) public void setDataSource(FileDescriptor fd, long offset, long length)
throws IOException, IllegalArgumentException, IllegalStateException {
disableProxyListener();
_setDataSource(fd, offset, length);
}
private native void _setDataSource(FileDescriptor fd, long offset, long length)
throws IOException, IllegalArgumentException, IllegalStateException; throws IOException, IllegalArgumentException, IllegalStateException;
/** /**
@@ -1332,6 +1351,8 @@ public class MediaPlayer
_reset(); _reset();
// make sure none of the listeners get called anymore // make sure none of the listeners get called anymore
mEventHandler.removeCallbacksAndMessages(null); mEventHandler.removeCallbacksAndMessages(null);
disableProxyListener();
} }
private native void _reset(); private native void _reset();
@@ -2449,4 +2470,57 @@ public class MediaPlayer
return (mode == VIDEO_SCALING_MODE_SCALE_TO_FIT || return (mode == VIDEO_SCALING_MODE_SCALE_TO_FIT ||
mode == VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING); mode == VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING);
} }
private Context mProxyContext = null;
private ProxyReceiver mProxyReceiver = null;
private void setupProxyListener(Context context) {
IntentFilter filter = new IntentFilter();
filter.addAction(Proxy.PROXY_CHANGE_ACTION);
mProxyReceiver = new ProxyReceiver();
mProxyContext = context;
Intent currentProxy =
context.getApplicationContext().registerReceiver(mProxyReceiver, filter);
if (currentProxy != null) {
handleProxyBroadcast(currentProxy);
}
}
private void disableProxyListener() {
if (mProxyReceiver == null) {
return;
}
Context appContext = mProxyContext.getApplicationContext();
if (appContext != null) {
appContext.unregisterReceiver(mProxyReceiver);
}
mProxyReceiver = null;
mProxyContext = null;
}
private void handleProxyBroadcast(Intent intent) {
ProxyProperties props =
(ProxyProperties)intent.getExtra(Proxy.EXTRA_PROXY_INFO);
if (props == null || props.getHost() == null) {
updateProxyConfig(null);
} else {
updateProxyConfig(props);
}
}
private class ProxyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Proxy.PROXY_CHANGE_ACTION)) {
handleProxyBroadcast(intent);
}
}
}
private native void updateProxyConfig(ProxyProperties props);
} }

View File

@@ -55,6 +55,10 @@ struct fields_t {
jfieldID surface_texture; jfieldID surface_texture;
jmethodID post_event; jmethodID post_event;
jmethodID proxyConfigGetHost;
jmethodID proxyConfigGetPort;
jmethodID proxyConfigGetExclusionList;
}; };
static fields_t fields; static fields_t fields;
@@ -622,6 +626,20 @@ android_media_MediaPlayer_native_init(JNIEnv *env)
if (fields.surface_texture == NULL) { if (fields.surface_texture == NULL) {
return; return;
} }
clazz = env->FindClass("android/net/ProxyProperties");
if (clazz == NULL) {
return;
}
fields.proxyConfigGetHost =
env->GetMethodID(clazz, "getHost", "()Ljava/lang/String;");
fields.proxyConfigGetPort =
env->GetMethodID(clazz, "getPort", "()I");
fields.proxyConfigGetExclusionList =
env->GetMethodID(clazz, "getExclusionList", "()Ljava/lang/String;");
} }
static void static void
@@ -823,6 +841,49 @@ android_media_MediaPlayer_setNextMediaPlayer(JNIEnv *env, jobject thiz, jobject
; ;
} }
static void
android_media_MediaPlayer_updateProxyConfig(
JNIEnv *env, jobject thiz, jobject proxyProps)
{
ALOGV("updateProxyConfig");
sp<MediaPlayer> thisplayer = getMediaPlayer(env, thiz);
if (thisplayer == NULL) {
return;
}
if (proxyProps == NULL) {
thisplayer->updateProxyConfig(
NULL /* host */, 0 /* port */, NULL /* exclusionList */);
} else {
jstring hostObj = (jstring)env->CallObjectMethod(
proxyProps, fields.proxyConfigGetHost);
const char *host = env->GetStringUTFChars(hostObj, NULL);
int port = env->CallIntMethod(proxyProps, fields.proxyConfigGetPort);
jstring exclusionListObj = (jstring)env->CallObjectMethod(
proxyProps, fields.proxyConfigGetExclusionList);
const char *exclusionList =
env->GetStringUTFChars(exclusionListObj, NULL);
if (host != NULL && exclusionListObj != NULL) {
thisplayer->updateProxyConfig(host, port, exclusionList);
}
if (exclusionList != NULL) {
env->ReleaseStringUTFChars(exclusionListObj, exclusionList);
exclusionList = NULL;
}
if (host != NULL) {
env->ReleaseStringUTFChars(hostObj, host);
host = NULL;
}
}
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
static JNINativeMethod gMethods[] = { static JNINativeMethod gMethods[] = {
@@ -832,7 +893,7 @@ static JNINativeMethod gMethods[] = {
(void *)android_media_MediaPlayer_setDataSourceAndHeaders (void *)android_media_MediaPlayer_setDataSourceAndHeaders
}, },
{"setDataSource", "(Ljava/io/FileDescriptor;JJ)V", (void *)android_media_MediaPlayer_setDataSourceFD}, {"_setDataSource", "(Ljava/io/FileDescriptor;JJ)V", (void *)android_media_MediaPlayer_setDataSourceFD},
{"_setVideoSurface", "(Landroid/view/Surface;)V", (void *)android_media_MediaPlayer_setVideoSurface}, {"_setVideoSurface", "(Landroid/view/Surface;)V", (void *)android_media_MediaPlayer_setVideoSurface},
{"prepare", "()V", (void *)android_media_MediaPlayer_prepare}, {"prepare", "()V", (void *)android_media_MediaPlayer_prepare},
{"prepareAsync", "()V", (void *)android_media_MediaPlayer_prepareAsync}, {"prepareAsync", "()V", (void *)android_media_MediaPlayer_prepareAsync},
@@ -867,6 +928,7 @@ static JNINativeMethod gMethods[] = {
{"getParameter", "(ILandroid/os/Parcel;)V", (void *)android_media_MediaPlayer_getParameter}, {"getParameter", "(ILandroid/os/Parcel;)V", (void *)android_media_MediaPlayer_getParameter},
{"native_setRetransmitEndpoint", "(Ljava/lang/String;I)I", (void *)android_media_MediaPlayer_setRetransmitEndpoint}, {"native_setRetransmitEndpoint", "(Ljava/lang/String;I)I", (void *)android_media_MediaPlayer_setRetransmitEndpoint},
{"setNextMediaPlayer", "(Landroid/media/MediaPlayer;)V", (void *)android_media_MediaPlayer_setNextMediaPlayer}, {"setNextMediaPlayer", "(Landroid/media/MediaPlayer;)V", (void *)android_media_MediaPlayer_setNextMediaPlayer},
{"updateProxyConfig", "(Landroid/net/ProxyProperties;)V", (void *)android_media_MediaPlayer_updateProxyConfig},
}; };
static const char* const kClassPathName = "android/media/MediaPlayer"; static const char* const kClassPathName = "android/media/MediaPlayer";