Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit be22605d authored by Andreas Huber's avatar Andreas Huber Committed by Android (Google) Code Review
Browse files

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

parents 05caa2a3 d5f9fa57
Loading
Loading
Loading
Loading
+76 −2
Original line number Diff line number Diff line
@@ -16,9 +16,14 @@

package android.media;

import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.AssetFileDescriptor;
import android.net.Proxy;
import android.net.ProxyProperties;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
@@ -864,6 +869,7 @@ public class MediaPlayer
     */
    public void setDataSource(Context context, Uri uri, Map<String, String> headers)
        throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
        disableProxyListener();

        String scheme = uri.getScheme();
        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");

        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)
            throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
        disableProxyListener();

        final Uri uri = Uri.parse(path);
        if ("file".equals(uri.getScheme())) {
            path = uri.getPath();
@@ -991,7 +1004,13 @@ public class MediaPlayer
     * @param length the length in bytes of the data to be played
     * @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;

    /**
@@ -1332,6 +1351,8 @@ public class MediaPlayer
        _reset();
        // make sure none of the listeners get called anymore
        mEventHandler.removeCallbacksAndMessages(null);

        disableProxyListener();
    }

    private native void _reset();
@@ -2449,4 +2470,57 @@ public class MediaPlayer
        return (mode == VIDEO_SCALING_MODE_SCALE_TO_FIT ||
                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);
}
+63 −1
Original line number Diff line number Diff line
@@ -55,6 +55,10 @@ struct fields_t {
    jfieldID    surface_texture;

    jmethodID   post_event;

    jmethodID   proxyConfigGetHost;
    jmethodID   proxyConfigGetPort;
    jmethodID   proxyConfigGetExclusionList;
};
static fields_t fields;

@@ -622,6 +626,20 @@ android_media_MediaPlayer_native_init(JNIEnv *env)
    if (fields.surface_texture == NULL) {
        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
@@ -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[] = {
@@ -832,7 +893,7 @@ static JNINativeMethod gMethods[] = {
        (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},
    {"prepare",             "()V",                              (void *)android_media_MediaPlayer_prepare},
    {"prepareAsync",        "()V",                              (void *)android_media_MediaPlayer_prepareAsync},
@@ -867,6 +928,7 @@ static JNINativeMethod gMethods[] = {
    {"getParameter",        "(ILandroid/os/Parcel;)V",          (void *)android_media_MediaPlayer_getParameter},
    {"native_setRetransmitEndpoint", "(Ljava/lang/String;I)I",  (void *)android_media_MediaPlayer_setRetransmitEndpoint},
    {"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";