New setDataSource API for accepting cookies

Bug:    34736056
Test:   Manual through the test app
Change-Id: Ibd48d5e292dda490d9e4e4528589b2b7ba97a4b4
This commit is contained in:
Hassan Shojania
2017-02-15 09:06:48 -08:00
parent 1ea19d3463
commit a6c969c036
6 changed files with 97 additions and 12 deletions

View File

@@ -22319,6 +22319,7 @@ package android.media {
method public void setAuxEffectSendLevel(float);
method public void setBufferingParams(android.media.BufferingParams);
method public void setDataSource(android.content.Context, android.net.Uri) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.SecurityException;
method public void setDataSource(android.content.Context, android.net.Uri, java.util.Map<java.lang.String, java.lang.String>, java.util.List<java.net.HttpCookie>) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.SecurityException;
method public void setDataSource(android.content.Context, android.net.Uri, java.util.Map<java.lang.String, java.lang.String>) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.SecurityException;
method public void setDataSource(java.lang.String) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.SecurityException;
method public void setDataSource(android.content.res.AssetFileDescriptor) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException;

View File

@@ -23962,6 +23962,7 @@ package android.media {
method public void setAuxEffectSendLevel(float);
method public void setBufferingParams(android.media.BufferingParams);
method public void setDataSource(android.content.Context, android.net.Uri) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.SecurityException;
method public void setDataSource(android.content.Context, android.net.Uri, java.util.Map<java.lang.String, java.lang.String>, java.util.List<java.net.HttpCookie>) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.SecurityException;
method public void setDataSource(android.content.Context, android.net.Uri, java.util.Map<java.lang.String, java.lang.String>) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.SecurityException;
method public void setDataSource(java.lang.String) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.SecurityException;
method public void setDataSource(android.content.res.AssetFileDescriptor) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException;

View File

@@ -22412,6 +22412,7 @@ package android.media {
method public void setAuxEffectSendLevel(float);
method public void setBufferingParams(android.media.BufferingParams);
method public void setDataSource(android.content.Context, android.net.Uri) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.SecurityException;
method public void setDataSource(android.content.Context, android.net.Uri, java.util.Map<java.lang.String, java.lang.String>, java.util.List<java.net.HttpCookie>) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.SecurityException;
method public void setDataSource(android.content.Context, android.net.Uri, java.util.Map<java.lang.String, java.lang.String>) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.SecurityException;
method public void setDataSource(java.lang.String) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.SecurityException;
method public void setDataSource(android.content.res.AssetFileDescriptor) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException;

View File

@@ -61,8 +61,9 @@ public class MediaHTTPConnection extends IMediaHTTPConnection.Stub {
private final static int MAX_REDIRECTS = 20;
public MediaHTTPConnection() {
if (CookieHandler.getDefault() == null) {
CookieHandler.setDefault(new CookieManager());
CookieManager cookieManager = (CookieManager)CookieHandler.getDefault();
if (cookieManager == null) {
Log.w(TAG, "MediaHTTPConnection: Unexpected. No CookieManager found.");
}
native_setup();

View File

@@ -19,25 +19,78 @@ package android.media;
import android.os.IBinder;
import android.util.Log;
import java.net.CookieHandler;
import java.net.CookieManager;
import java.net.CookieStore;
import java.net.HttpCookie;
import java.util.List;
/** @hide */
public class MediaHTTPService extends IMediaHTTPService.Stub {
private static final String TAG = "MediaHTTPService";
private List<HttpCookie> mCookies;
private Boolean mCookieStoreInitialized = new Boolean(false);
public MediaHTTPService() {
public MediaHTTPService(List<HttpCookie> cookies) {
mCookies = cookies;
Log.v(TAG, "MediaHTTPService(" + this + "): Cookies: " + cookies);
}
public IMediaHTTPConnection makeHTTPConnection() {
synchronized (mCookieStoreInitialized) {
// Only need to do it once for all connections
if ( !mCookieStoreInitialized ) {
CookieManager cookieManager = (CookieManager)CookieHandler.getDefault();
if (cookieManager == null) {
cookieManager = new CookieManager();
CookieHandler.setDefault(cookieManager);
Log.v(TAG, "makeHTTPConnection: CookieManager created: " + cookieManager);
}
else {
Log.v(TAG, "makeHTTPConnection: CookieManager(" + cookieManager + ") exists.");
}
// Applying the bootstrapping cookies
if ( mCookies != null ) {
CookieStore store = cookieManager.getCookieStore();
for ( HttpCookie cookie : mCookies ) {
try {
store.add(null, cookie);
} catch ( Exception e ) {
Log.v(TAG, "makeHTTPConnection: CookieStore.add" + e);
}
//for extended debugging when needed
//Log.v(TAG, "MediaHTTPConnection adding Cookie[" + cookie.getName() +
// "]: " + cookie);
}
} // mCookies
mCookieStoreInitialized = true;
Log.v(TAG, "makeHTTPConnection(" + this + "): cookieManager: " + cookieManager +
" Cookies: " + mCookies);
} // mCookieStoreInitialized
} // synchronized
return new MediaHTTPConnection();
}
/* package private */static IBinder createHttpServiceBinderIfNecessary(
String path) {
return createHttpServiceBinderIfNecessary(path, null);
}
// when cookies are provided
static IBinder createHttpServiceBinderIfNecessary(
String path, List<HttpCookie> cookies) {
if (path.startsWith("http://") || path.startsWith("https://")) {
return (new MediaHTTPService()).asBinder();
return (new MediaHTTPService(cookies)).asBinder();
} else if (path.startsWith("widevine://")) {
Log.d(TAG, "Widevine classic is no longer supported");
}
return null;
}
}

View File

@@ -73,6 +73,7 @@ import java.lang.Runnable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.ref.WeakReference;
import java.net.HttpCookie;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.URL;
@@ -80,6 +81,7 @@ import java.nio.ByteOrder;
import java.util.Arrays;
import java.util.BitSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
@@ -998,7 +1000,7 @@ public class MediaPlayer extends PlayerBase
*/
public void setDataSource(@NonNull Context context, @NonNull Uri uri)
throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
setDataSource(context, uri, null);
setDataSource(context, uri, null, null);
}
/**
@@ -1011,11 +1013,13 @@ public class MediaPlayer extends PlayerBase
* changed with key/value pairs through the headers parameter with
* "android-allow-cross-domain-redirect" as the key and "0" or "1" as the value
* to disallow or allow cross domain redirection.
* The headers must not include cookies. Instead, use the cookies param.
* @param cookies the cookies to be sent together with the request
* @throws IllegalStateException if it is called in an invalid state
*/
public void setDataSource(@NonNull Context context, @NonNull Uri uri,
@Nullable Map<String, String> headers) throws IOException, IllegalArgumentException,
SecurityException, IllegalStateException {
@Nullable Map<String, String> headers, @Nullable List<HttpCookie> cookies)
throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
// The context and URI usually belong to the calling user. Get a resolver for that user
// and strip out the userId from the URI if present.
final ContentResolver resolver = context.getContentResolver();
@@ -1036,18 +1040,36 @@ public class MediaPlayer extends PlayerBase
} else if (attemptDataSource(resolver, actualUri)) {
return;
} else {
setDataSource(uri.toString(), headers);
setDataSource(uri.toString(), headers, cookies);
}
} else {
// Try requested Uri locally first, or fallback to media server
if (attemptDataSource(resolver, uri)) {
return;
} else {
setDataSource(uri.toString(), headers);
setDataSource(uri.toString(), headers, cookies);
}
}
}
/**
* 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
* Note that the cross domain redirection is allowed by default, but that can be
* changed with key/value pairs through the headers parameter with
* "android-allow-cross-domain-redirect" as the key and "0" or "1" as the value
* to disallow or allow cross domain redirection.
* @throws IllegalStateException if it is called in an invalid state
*/
public void setDataSource(@NonNull Context context, @NonNull Uri uri,
@Nullable Map<String, String> headers)
throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
setDataSource(context, uri, headers, null);
}
private boolean attemptDataSource(ContentResolver resolver, Uri uri) {
try (AssetFileDescriptor afd = resolver.openAssetFileDescriptor(uri, "r")) {
setDataSource(afd);
@@ -1085,6 +1107,11 @@ public class MediaPlayer extends PlayerBase
* @hide pending API council
*/
public void setDataSource(String path, Map<String, String> headers)
throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
setDataSource(path, headers, null);
}
private void setDataSource(String path, Map<String, String> headers, List<HttpCookie> cookies)
throws IOException, IllegalArgumentException, SecurityException, IllegalStateException
{
String[] keys = null;
@@ -1101,10 +1128,11 @@ public class MediaPlayer extends PlayerBase
++i;
}
}
setDataSource(path, keys, values);
setDataSource(path, keys, values, cookies);
}
private void setDataSource(String path, String[] keys, String[] values)
private void setDataSource(String path, String[] keys, String[] values,
List<HttpCookie> cookies)
throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
final Uri uri = Uri.parse(path);
final String scheme = uri.getScheme();
@@ -1113,7 +1141,7 @@ public class MediaPlayer extends PlayerBase
} else if (scheme != null) {
// handle non-file sources
nativeSetDataSource(
MediaHTTPService.createHttpServiceBinderIfNecessary(path),
MediaHTTPService.createHttpServiceBinderIfNecessary(path, cookies),
path,
keys,
values);