New setDataSource API for accepting cookies
Bug: 34736056 Test: Manual through the test app Change-Id: Ibd48d5e292dda490d9e4e4528589b2b7ba97a4b4
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user