am fc6f6134: Widevine sample player For bug 4245169

* commit 'fc6f6134e96736344f9431572de279a3963b9ffc':
  Widevine sample player For bug 4245169
This commit is contained in:
Gloria Wang
2011-04-07 14:24:02 -07:00
committed by Android Git Automerger
46 changed files with 2011 additions and 0 deletions

View File

@@ -0,0 +1,15 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_PACKAGE_NAME := WidevineSamplePlayer
LOCAL_SDK_VERSION := current
include $(BUILD_PACKAGE)
# Use the following include to make our test apk.
include $(call all-makefiles-under,$(LOCAL_PATH))

View File

@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.widevine.demo"
>
<uses-permission android:name="android.permission.INTERNET" />
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".WidevineSamplePlayer"
android:label="@string/app_name"
android:screenOrientation="landscape">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".VideoPlayerView"
android:label="@string/app_name"
android:screenOrientation="landscape">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
</intent-filter>
</activity>
<activity android:name=".StreamingActivity"
android:label="@string/app_name"
android:screenOrientation="landscape">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
</intent-filter>
</activity>
<activity android:name=".DownloadActivity"
android:label="@string/app_name"
android:screenOrientation="landscape">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
</intent-filter>
</activity>
<activity android:name=".SettingsActivity"
android:label="@string/app_name"
android:screenOrientation="landscape">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
</intent-filter>
</activity>
</application>
</manifest>

View File

@@ -0,0 +1,2 @@
# Project target.
target=android-12

View File

@@ -0,0 +1,45 @@
README: WidevineSamplePlayer.apk
[Install application:]
Attach a device
In a terminal window:
change directory to vendor/widevine/proprietary/samplePlayer
type the following commands:
mm
adb root
adb remount
adb sync
adb reboot
demo is installed to out/target/product/stingray/system/app/WidevineSamplePlayer.apk
[Download content for offline testing:]
View http://seawwws001.shibboleth.tv/android/oem.html source for asset names.
For example:
curl -sL "http://seawwws001.cdn.shibboleth.tv/videos/content/starz_demo_ffmpeg_hc_single_720p.wvm" -O
adb shell mkdir -p /sdcard/Widevine
adb push starz_demo_ffmpeg_hc_single_720p.wvm /sdcard/Widevine/
[Running the application:]
On your device, open WidevineDemo.
The Streaming tab should be highlighted, with content available in 480p and 720p encodings.
Select an asset to play.
You should see a player page. To successfully play back content:
-Select Acquire Rights
-Select Play (or click the player window to start playback)
Selecting Show Rights will provide the license time left for playback in the log screen next to the player.
Selecting Remove Rights will stop further attempts to play back from succeeding for more than 10 seconds. You will need to then select Acquire Rights to allow playback again.
Stop video, and go back one screen to the video list.
Select the Downloads tab.
You should see the video we pushed to the device (starz_demo_ffmpeg_hc_single_720p.wvm).
Behavior on this page should be the same as for the Streaming page, with the exception that once you Acquire Rights, you should be able to continue playback of the Downloaded asset offline as long as the rights are valid. You can check the status of your rights with the Show Rights button.

Binary file not shown.

After

Width:  |  Height:  |  Size: 662 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 313 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 376 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 662 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 313 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 376 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 662 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 313 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 376 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView android:id="@+id/textView1" android:text="@string/no_content" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="40pt" android:background="@drawable/background3" android:gravity="center"></TextView>
</LinearLayout>

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/tabhost"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="5dp">
<TabWidget
android:id="@android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</LinearLayout>
</TabHost>

View File

@@ -0,0 +1,88 @@
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:stretchColumns="1"
android:background="@drawable/background3">
<TableRow android:paddingTop="50dip" >
<TextView
android:layout_width="200dip"
android:layout_height="wrap_content"
android:layout_column="1"
android:typeface="serif"
android:textSize="30sp"
android:paddingLeft="100dip"
android:text="@string/drm_server"/>
<EditText
android:layout_width="600dip"
android:layout_height="wrap_content"
android:id="@+id/drm_server"
/>
</TableRow>
<TableRow>
<TextView
android:layout_width="200dip"
android:layout_height="wrap_content"
android:layout_column="1"
android:typeface="serif"
android:textSize="30sp"
android:paddingLeft="100dip"
android:text="@string/device_id"/>
<EditText
android:layout_width="600dip"
android:layout_height="wrap_content"
android:id="@+id/device_id"
/>
</TableRow>
<TableRow
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="200dip"
android:layout_height="wrap_content"
android:layout_column="1"
android:typeface="serif"
android:textSize="30sp"
android:paddingLeft="100dip"
android:text="@string/portal_id"/>
<EditText
android:layout_width="600dip"
android:layout_height="wrap_content"
android:id="@+id/portal_id"
/>
</TableRow>
<TableRow
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="200dip"
android:layout_height="wrap_content"
android:layout_column="1"
android:typeface="serif"
android:textSize="30sp"
android:paddingLeft="100dip"
android:text="@string/content_page"/>
<EditText
android:layout_width="600dip"
android:layout_height="wrap_content"
android:id="@+id/content_page"
/>
</TableRow>
<TableRow
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
>
<Button
android:text="@string/update_button"
android:id="@+id/update_button"
/>
</TableRow>
</TableLayout>

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Widevine Demo</string>
<string name="no_content">No Content Found</string>
<string name="play">Play</string>
<string name="stop">Stop</string>
<string name="constraints">Constraints</string>
<string name="acquire_rights">Acquire Rights</string>
<string name="remove_rights">Remove Rights</string>
<string name="show_rights">Show Rights</string>
<string name="streaming">Streaming</string>
<string name="downloads">Downloads</string>
<string name="content_page">Content Page</string>
<string name="device_id">Device Id</string>
<string name="drm_server">Drm Server</string>
<string name="portal_id">Portal Name</string>
<string name="update_button">Update Button</string>
</resources>

View File

@@ -0,0 +1,281 @@
/*
* (c)Copyright 2011 Widevine Technologies, Inc
*/
package com.widevine.demo;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.ArrayList;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Button;
public abstract class AssetActivity extends Activity {
private int currentPage;
protected ArrayList<AssetsPage> pages;
private Context context;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
context = this;
initialize();
}
protected void initialize() {
currentPage = 0;
pages = new ArrayList<AssetsPage>();
if (setUpAssetPages()) {
setContentView(createView(this));
} else {
setContentView(R.layout.empty);
}
}
protected abstract boolean setUpAssetPages();
private View createView(Context ctxt) {
ImageView empty = new ImageView(this);
empty.setBackgroundDrawable(getResources().getDrawable(R.drawable.empty));
View[] clips = new View[6];
BitmapFactory.Options options = new BitmapFactory.Options();
options.inDither = true;
AssetsPage page = pages.get(currentPage);
for (int i = 0; i < page.getPageCount(); i++) {
AssetItem assetItem = page.getPage(i);
clips[i] = createViewItem(getBitmapFromAssetItem(assetItem), assetItem.getAssetPath(),
assetItem.getTitle());
}
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.FILL_PARENT, 1);
params.gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP;
LinearLayout.LayoutParams paramsMain = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.FILL_PARENT, 1);
paramsMain.gravity = Gravity.CENTER;
LinearLayout left = new LinearLayout(ctxt);
left.setOrientation(LinearLayout.VERTICAL);
if (clips[0] != null) {
left.addView(clips[0], params);
}
if (clips[3] != null) {
left.addView(clips[3], params);
} else {
left.addView(createEmptyView(), params);
}
LinearLayout middle = new LinearLayout(ctxt);
middle.setOrientation(LinearLayout.VERTICAL);
if (clips[1] != null) {
middle.addView(clips[1], params);
}
if (clips[4] != null) {
middle.addView(clips[4], params);
} else {
middle.addView(createEmptyView(), params);
}
LinearLayout right = new LinearLayout(ctxt);
right.setOrientation(LinearLayout.VERTICAL);
if (clips[2] != null) {
right.addView(clips[2], params);
}
params.gravity = Gravity.BOTTOM;
if (clips[5] != null) {
right.addView(clips[5], params);
} else {
right.addView(createEmptyView(), params);
}
params.gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP;
LinearLayout body = new LinearLayout(ctxt);
body.addView(left, paramsMain);
body.addView(middle, paramsMain);
body.addView(right, paramsMain);
// Next button listener
View.OnClickListener nextButtonListener = new View.OnClickListener() {
public void onClick(View v) {
currentPage++;
if (currentPage >= pages.size()) {
currentPage = 0;
}
setContentView(createView(context));
}
};
Button next = new Button(this);
next.setText(">>");
next.setOnClickListener(nextButtonListener);
// Previous button listener
View.OnClickListener prevButtonListener = new View.OnClickListener() {
public void onClick(View v) {
currentPage--;
if (currentPage < 0) {
currentPage = pages.size() - 1;
}
setContentView(createView(context));
}
};
Button prev = new Button(this);
prev.setText("<<");
prev.setOnClickListener(prevButtonListener);
LinearLayout buttons = new LinearLayout(this);
buttons.addView(prev, params);
buttons.addView(next, params);
body.setBackgroundDrawable(this.getResources().getDrawable(R.drawable.background3));
SwipeLinearLayout main = new SwipeLinearLayout(this);
main.setNext(nextButtonListener);
main.setPrev(prevButtonListener);
main.setOrientation(LinearLayout.VERTICAL);
main.addView(body, params);
LinearLayout.LayoutParams paramButtons = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
paramButtons.gravity = Gravity.CENTER;
main.addView(buttons, paramButtons);
return main;
}
private View createEmptyView() {
ImageView empty = new ImageView(this);
empty.setBackgroundDrawable(getResources().getDrawable(R.drawable.empty));
TextView emptyText = new TextView(this);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT, 1);
params.gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP;
LinearLayout body = new LinearLayout(this);
body.setOrientation(LinearLayout.VERTICAL);
body.addView(empty, params);
body.addView(emptyText, params);
return body;
}
private View createViewItem(Bitmap image, String path, String title) {
final String assetPath = path;
ClipImageView clip = new ClipImageView(this);
clip.setImageBitmap(image);
// Set the onClick listener for each image
clip.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent(context, VideoPlayerView.class);
intent.putExtra("com.widevine.demo.Path", assetPath);
context.startActivity(intent);
}
});
TextView text = new TextView(this);
text.setText((title == null) ? path : title);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT, 1);
params.gravity = Gravity.CENTER;
LinearLayout body = new LinearLayout(this);
body.setOrientation(LinearLayout.VERTICAL);
body.addView(clip, params);
body.addView(text, params);
return body;
}
private Bitmap getBitmapFromAssetItem(AssetItem assetItem) {
Bitmap clipImage = null;
String imageUrl = null;
if (assetItem.getImagePath() == null || assetItem.getImagePath().equals("")) {
if (assetItem.getAssetPath().indexOf("http") == -1)
clipImage = BitmapFactory.decodeResource(getResources(), R.drawable.download_clip);
else
clipImage = BitmapFactory.decodeResource(getResources(), R.drawable.streaming_clip);
} else {
InputStream bitmapStream = null;
if (assetItem.getAssetPath().indexOf("http") != -1) {
imageUrl = assetItem.getImagePath();
if (imageUrl != null) {
ImageHandler imageHandler = new ImageHandler(imageUrl);
imageHandler.start();
try {
imageHandler.join();
} catch (InterruptedException e) {
}
clipImage = imageHandler.getBitmap();
}
} else {
try {
bitmapStream = new FileInputStream(assetItem.getImagePath());
} catch (FileNotFoundException e) {
bitmapStream = null;
}
clipImage = BitmapFactory.decodeStream(bitmapStream);
}
if (clipImage == null) {
clipImage = BitmapFactory.decodeResource(getResources(), R.drawable.streaming_clip);
}
}
return clipImage;
}
}

View File

@@ -0,0 +1,65 @@
/*
* (c)Copyright 2011 Widevine Technologies, Inc
*/
package com.widevine.demo;
/**
* Describes one asset in the list view
*/
public class AssetDescriptor {
private String mThumbnail;
private String mTitle;
private String mDescription;
private String mUri;
private String mStatus;
public AssetDescriptor copy() {
AssetDescriptor ad = new AssetDescriptor();
ad.setTitle(mTitle);
ad.setThumbnail(mThumbnail);
ad.setDescription(mDescription);
ad.setUri(mUri);
return ad;
}
public String getThumbnail() {
return mThumbnail;
}
public void setThumbnail(String thumbnail) {
mThumbnail = thumbnail;
}
public String getTitle() {
return mTitle;
}
public void setTitle(String title) {
mTitle = title;
}
public String getDescription() {
return mDescription;
}
public void setDescription(String description) {
mDescription = description;
}
public String getUri() {
return mUri;
}
public void setUri(String uri) {
mUri = uri;
}
public String getStatus() {
return mStatus;
}
public void setStatus(String status) {
mStatus = status;
}
}

View File

@@ -0,0 +1,35 @@
/*
* (c)Copyright 2011 Widevine Technologies, Inc
*/
package com.widevine.demo;
public class AssetItem {
private String assetPath;
private String imagePath;
private String title;
public AssetItem() {
assetPath = null;
imagePath = null;
title = null;
}
public AssetItem(String assetPath, String imagePath, String title) {
this.assetPath = assetPath;
this.imagePath = imagePath;
this.title = title;
}
public String getAssetPath() {
return assetPath;
}
public String getImagePath() {
return imagePath;
}
public String getTitle() {
return title;
}
}

View File

@@ -0,0 +1,29 @@
/*
* (c)Copyright 2011 Widevine Technologies, Inc
*/
package com.widevine.demo;
import java.util.ArrayList;
public class AssetsPage {
public static final int MAX_ITEMS = 6;
private ArrayList<AssetItem> assets;
public AssetsPage() {
assets = new ArrayList<AssetItem>();
}
public void addPage(String assetPath, String imagePath, String title) {
assets.add(new AssetItem(assetPath, imagePath, title));
}
public AssetItem getPage(int pageNumber) {
return assets.get(pageNumber);
}
public int getPageCount() {
return assets.size();
}
}

View File

@@ -0,0 +1,72 @@
/*
* (c)Copyright 2011 Widevine Technologies, Inc
*/
package com.widevine.demo;
import android.widget.ImageView;
import android.view.MotionEvent;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Rect;
public class ClipImageView extends ImageView {
private boolean touchedDown;
private float touchX, touchY, radius;
private boolean radiusInc;
private Bitmap selectCircle;
public ClipImageView(Context ctxt) {
super(ctxt);
touchedDown = false;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inDither = true;
selectCircle = BitmapFactory.decodeResource(getResources(), R.drawable.selection_circle,
options);
}
@Override
public boolean onTouchEvent(MotionEvent e) {
if (e.getAction() == MotionEvent.ACTION_DOWN) {
touchX = e.getX();
touchY = e.getY();
radius = 60;
radiusInc = false;
touchedDown = true;
} else if (e.getAction() == MotionEvent.ACTION_UP) {
touchedDown = false;
}
// return true;
return super.onTouchEvent(e);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (touchedDown) {
canvas.drawBitmap(selectCircle, null, new Rect((int) (touchX - radius),
(int) (touchY - radius), (int) (touchX + radius),
(int) (touchY + radius)), null);
if (radiusInc) {
radius += 5;
}
else {
radius -= 5;
}
if (radius >= 60 || radius <= 0) {
radiusInc = !radiusInc;
}
}
invalidate();
}
}

View File

@@ -0,0 +1,91 @@
/*
* (c)Copyright 2011 Widevine Technologies, Inc
*/
package com.widevine.demo;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import android.sax.Element;
import android.sax.EndElementListener;
import android.sax.EndTextElementListener;
import android.sax.RootElement;
import android.util.Xml;
/**
* Parser for the XML configuration file that defines the assets available to
* play
*/
public class ConfigXMLParser {
private URL mFeedUrl;
private InputStream inputStream;
protected InputStream getInputStream() {
try {
if (inputStream != null)
return inputStream;
else
return mFeedUrl.openConnection().getInputStream();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public ConfigXMLParser(URL feedUrl) {
mFeedUrl = feedUrl;
}
public ConfigXMLParser(InputStream inputStream) {
this.inputStream = inputStream;
}
public List<AssetDescriptor> parse() {
final AssetDescriptor currentAssetDescriptor = new AssetDescriptor();
RootElement root = new RootElement("widevine");
final List<AssetDescriptor> assetDescriptors = new ArrayList<AssetDescriptor>();
Element assetlist = root.getChild("asset-list");
Element asset = assetlist.getChild("asset");
asset.setEndElementListener(new EndElementListener() {
public void end() {
if (currentAssetDescriptor.getUri().indexOf("http") != -1
&& (currentAssetDescriptor.getUri().indexOf(".wvm") != -1
|| !currentAssetDescriptor.getUri().substring(currentAssetDescriptor
.getUri().lastIndexOf("/")).contains("."))) {
assetDescriptors.add(currentAssetDescriptor.copy());
}
}
});
asset.getChild("title").setEndTextElementListener(new EndTextElementListener() {
public void end(String body) {
currentAssetDescriptor.setTitle(body);
}
});
asset.getChild("uri").setEndTextElementListener(new EndTextElementListener() {
public void end(String body) {
currentAssetDescriptor.setUri(body);
}
});
asset.getChild("description").setEndTextElementListener(new EndTextElementListener() {
public void end(String body) {
currentAssetDescriptor.setDescription(body);
}
});
asset.getChild("thumbnail").setEndTextElementListener(new EndTextElementListener() {
public void end(String body) {
currentAssetDescriptor.setThumbnail(body);
}
});
try {
Xml.parse(this.getInputStream(), Xml.Encoding.UTF_8, root.getContentHandler());
} catch (Exception e) {
throw new RuntimeException(e);
}
return assetDescriptors;
}
}

View File

@@ -0,0 +1,52 @@
/*
* (c)Copyright 2011 Widevine Technologies, Inc
*/
package com.widevine.demo;
import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
public class DownloadActivity extends AssetActivity {
protected boolean setUpAssetPages() {
pages = new ArrayList<AssetsPage>();
File[] assets = getDownloadedClips();
if (assets != null && assets.length > 0) {
for (int i = 0; i < assets.length;) {
AssetsPage page = new AssetsPage();
for (int j = 0; j < AssetsPage.MAX_ITEMS && i < assets.length; j++, i++) {
page.addPage(assets[i].getAbsolutePath(), null, null);
}
pages.add(page);
}
return true;
} else {
return false;
}
}
private File[] getDownloadedClips() {
File file = new File("/sdcard/Widevine");
FilenameFilter filter = new FilenameFilter() {
public boolean accept(File dir, String name) {
File file = new File(dir.getAbsolutePath() + File.separator + name);
if (!file.isDirectory()
&& !name.equals("curl")
&& (name.contains(".wvm") || name.contains(".mp4") || !name.contains(".")))
return true;
else
return false;
}
};
return file.listFiles(filter);
}
}

View File

@@ -0,0 +1,79 @@
/*
* (c)Copyright 2011 Widevine Technologies, Inc
*/
package com.widevine.demo;
import android.content.Context;
import android.widget.VideoView;
public class FullScreenVideoView extends VideoView {
private boolean fullscreen;
private int rLeft, rRight, rTop, rBottom, regularHeight, regularWidth;
private int fullScreenWidth, fullScreenHeight;
public FullScreenVideoView(Context context) {
super(context);
fullscreen = false;
regularHeight = 0;
regularWidth = 0;
rBottom = 0;
rRight = 0;
rTop = 0;
rLeft = 0;
fullScreenWidth = 1280;
fullScreenHeight = 800;
}
public void setFullScreenDimensions(int width, int height) {
fullScreenWidth = width;
fullScreenHeight = height;
}
public void setFullScreen(boolean fullscreen) {
this.fullscreen = fullscreen;
this.requestLayout();
}
public boolean getFullScreen() {
return this.fullscreen;
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
if (rLeft == 0 && rRight == 0 && rTop == 0 && rBottom == 0) {
rBottom = bottom;
rRight = right;
rTop = top;
rLeft = left;
}
if (fullscreen) {
super.onLayout(true, left, top, fullScreenWidth, fullScreenHeight);
} else {
if (rLeft == 0 && rRight == 0 && rTop == 0 && rBottom == 0) {
super.onLayout(changed, left, top, right, bottom);
} else {
super.onLayout(changed, rLeft, rTop, rRight, rBottom);
}
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (regularHeight == 0 && regularWidth == 0) {
regularHeight = heightMeasureSpec;
regularWidth = widthMeasureSpec;
}
if (fullscreen) {
this.setMeasuredDimension(fullScreenWidth, fullScreenHeight);
} else {
if (regularHeight == 0 && regularWidth == 0) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
} else {
super.onMeasure(regularWidth, regularHeight);
}
}
}
}

View File

@@ -0,0 +1,111 @@
/*
* (c)Copyright 2011 Widevine Technologies, Inc
*/
package com.widevine.demo;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.util.ArrayList;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
public class HttpParser extends Thread {
private ArrayList<AssetItem> assets;
private String urlString;
private String rootUrl;
public HttpParser(String urlString) {
this.urlString = urlString;
this.assets = new ArrayList<AssetItem>();
this.rootUrl = this.urlString.substring(0, this.urlString.lastIndexOf("/") + 1);
}
public void run() {
try {
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpGet request = new HttpGet(urlString);
HttpResponse response = httpClient.execute(request);
InputStream reader = response.getEntity().getContent();
StringBuffer buffer = new StringBuffer();
int data = 0;
do {
data = reader.read();
if (data == -1) {
break;
}
buffer.append((char) data);
} while (true);
if (urlString.contains(".htm")) {
parseHtml(buffer.toString());
} else if (urlString.contains(".xml")) {
parseXML(buffer.toString());
}
} catch (MalformedURLException e) {
} catch (IOException e) {
}
}
private void parseXML(String xmlText) {
ConfigXMLParser parser = new ConfigXMLParser(new ByteArrayInputStream(xmlText.getBytes()));
ArrayList<AssetDescriptor> descrs = (ArrayList<AssetDescriptor>) parser.parse();
for (int i = 0; i < descrs.size(); i++) {
AssetDescriptor asset = descrs.get(i);
String imagePath = asset.getThumbnail();
if (!imagePath.contains("http")) {
imagePath = rootUrl + imagePath;
}
assets.add(new AssetItem(asset.getUri(), asset.getThumbnail(), asset.getTitle()));
}
}
private void parseHtml(String htmlText) {
int start = 0;
int end = 0;
while (true) {
String assetPath = null;
String title = null;
String imagePath = null;
start = htmlText.indexOf(":", start);
if (start == -1) {
break;
} else {
end = htmlText.indexOf("\"", start);
assetPath = "http" + htmlText.substring(start, end);
start = end + 1;
start = htmlText.indexOf("\"", start) + 1;
end = htmlText.indexOf("\"", start);
imagePath = htmlText.substring(start, end);
if (!imagePath.contains("http")) {
imagePath = rootUrl + imagePath;
}
start = htmlText.indexOf("<p>", start) + "<p>".length();
end = htmlText.indexOf("</p>", start);
title = htmlText.substring(start, end);
start = end + 1;
assets.add(new AssetItem(assetPath, imagePath, title));
}
}
}
public ArrayList<AssetItem> getAssets() {
return this.assets;
}
}

View File

@@ -0,0 +1,56 @@
/*
* (c)Copyright 2011 Widevine Technologies, Inc
*/
package com.widevine.demo;
import java.io.IOException;
import java.net.MalformedURLException;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
public class ImageHandler extends Thread {
private boolean scale;
private String imageUrl;
private Bitmap clipImage = null;
public ImageHandler(String imageUrl) {
this.imageUrl = imageUrl;
this.clipImage = null;
}
public void setScale(boolean scale) {
this.scale = scale;
}
public void run() {
try {
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpGet request = new HttpGet(imageUrl);
HttpResponse response = httpClient.execute(request);
this.clipImage = BitmapFactory.decodeStream(response.getEntity().getContent());
if (scale) {
this.clipImage = Bitmap.createScaledBitmap(this.clipImage, 150, 200, false);
}
} catch (MalformedURLException e) {
this.clipImage = null;
} catch (IOException e) {
this.clipImage = null;
}
}
public Bitmap getBitmap() {
return this.clipImage;
}
}

View File

@@ -0,0 +1,73 @@
/*
* (c)Copyright 2011 Widevine Technologies, Inc
*/
package com.widevine.demo;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.content.Context;
public class SettingsActivity extends Activity {
// public static String CONTENT_PAGE = "/sdcard/Widevine/config.xml";
public static String CONTENT_PAGE = "http://seawwws001.shibboleth.tv/android/oem.html";
private Context context;
private Button updateButton;
private EditText drmServer, portalName, deviceId, contentPage;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
context = this;
setContentView(R.layout.settings);
updateButton = (Button) findViewById(R.id.update_button);
View.OnClickListener clickListener = new View.OnClickListener() {
public void onClick(View v) {
WidevineDrm.Settings.DRM_SERVER_URI = drmServer.getText().toString();
WidevineDrm.Settings.DEVICE_ID = deviceId.getText().toString();
WidevineDrm.Settings.PORTAL_NAME = portalName.getText().toString();
SettingsActivity.CONTENT_PAGE = contentPage.getText().toString();
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setMessage("DRM Settings Updated").setCancelable(false)
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alert = builder.create();
alert.show();
}
};
updateButton.setOnClickListener(clickListener);
drmServer = (EditText) findViewById(R.id.drm_server);
drmServer.setText(WidevineDrm.Settings.DRM_SERVER_URI);
deviceId = (EditText) findViewById(R.id.device_id);
deviceId.setText(WidevineDrm.Settings.DEVICE_ID);
portalName = (EditText) findViewById(R.id.portal_id);
portalName.setText(WidevineDrm.Settings.PORTAL_NAME);
contentPage = (EditText) findViewById(R.id.content_page);
contentPage.setText(SettingsActivity.CONTENT_PAGE);
}
}

View File

@@ -0,0 +1,97 @@
/*
* (c)Copyright 2011 Widevine Technologies, Inc
*/
package com.widevine.demo;
import java.io.File;
import java.net.MalformedURLException;
import java.util.ArrayList;
import android.os.Bundle;
public class StreamingActivity extends AssetActivity {
private String contentPage;
@Override
public void onCreate(Bundle savedInstanceState) {
contentPage = SettingsActivity.CONTENT_PAGE;
super.onCreate(savedInstanceState);
}
@Override
public void onResume() {
super.onResume();
if (!contentPage.equals(SettingsActivity.CONTENT_PAGE)) {
contentPage = SettingsActivity.CONTENT_PAGE;
initialize();
}
}
protected boolean setUpAssetPages() {
pages = new ArrayList<AssetsPage>();
if (contentPage.contains(".htm")) {
ArrayList<AssetItem> assets = getStreamingClipsHttp();
if (assets == null || assets.size() == 0)
return false;
for (int i = 0; i < assets.size();) {
AssetsPage page = new AssetsPage();
for (int j = 0; j < AssetsPage.MAX_ITEMS && i < assets.size(); j++, i++) {
page.addPage(assets.get(i).getAssetPath(), assets.get(i).getImagePath(), assets
.get(i).getTitle());
}
pages.add(page);
}
} else {
ArrayList<AssetDescriptor> assets = getStreamingClipsXml();
if (assets == null || assets.size() == 0)
return false;
for (int i = 0; i < assets.size();) {
AssetsPage page = new AssetsPage();
for (int j = 0; j < AssetsPage.MAX_ITEMS && i < assets.size(); j++, i++) {
page.addPage(assets.get(i).getUri(), assets.get(i).getThumbnail(), assets
.get(i).getTitle());
}
pages.add(page);
}
}
return true;
}
private ArrayList<AssetDescriptor> getStreamingClipsXml() {
try {
File file = new File(contentPage);
if (file.exists()) {
ConfigXMLParser parser = new ConfigXMLParser(file.toURL());
ArrayList<AssetDescriptor> assets = (ArrayList<AssetDescriptor>) parser.parse();
return assets;
} else {
return new ArrayList<AssetDescriptor>();
}
} catch (MalformedURLException e) {
return new ArrayList<AssetDescriptor>();
}
}
private ArrayList<AssetItem> getStreamingClipsHttp() {
HttpParser parser = new HttpParser(contentPage);
parser.start();
try {
parser.join();
} catch (InterruptedException e) {
}
return parser.getAssets();
}
}

View File

@@ -0,0 +1,58 @@
/*
* (c)Copyright 2011 Widevine Technologies, Inc
*/
package com.widevine.demo;
import android.content.Context;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;
public class SwipeLinearLayout extends LinearLayout {
private View.OnClickListener prev;
private View.OnClickListener next;
float startX, startY, endX, endY;
public SwipeLinearLayout(Context c) {
super(c);
}
public void setNext(View.OnClickListener next) {
this.next = next;
}
public void setPrev(View.OnClickListener prev) {
this.prev = prev;
}
public boolean onTouchEvent(MotionEvent e) {
if (e.getAction() == MotionEvent.ACTION_DOWN) {
startX = e.getX();
startY = e.getY();
return true;
} else if (e.getAction() == MotionEvent.ACTION_UP) {
endX = e.getX();
endY = e.getY();
if (Math.abs(startY - endY) < 75) {
if ((startX - endX) > 200.0) {
// go forward
if (next != null) {
next.onClick(null);
}
} else if ((startX - endX) < -200.0) {
// go back
if (prev != null) {
prev.onClick(null);
}
}
startX = startY = endX = endY = 0;
}
return true;
}
return false;
}
}

View File

@@ -0,0 +1,329 @@
/*
* (c)Copyright 2011 Widevine Technologies, Inc
*/
package com.widevine.demo;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.MediaController;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Button;
import android.view.Gravity;
import android.view.View;
import android.content.Context;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnErrorListener;
import android.media.MediaPlayer.OnCompletionListener;
public class VideoPlayerView extends Activity {
private final static String EXIT_FULLSCREEN = "Exit Full Screen";
private final static String FULLSCREEN = "Enter Full Screen";
private final static String PLAY = "Play";
private final static int REFRESH = 1;
private WidevineDrm drm;
private FullScreenVideoView videoView;
private String assetUri;
private TextView logs;
private ScrollView scrollView;
private Context context;
private ClipImageView bgImage;
private Button playButton;
private Button fullScreen;
private Handler hRefresh;
private View contentView;
private LinearLayout main;
private LinearLayout sidePanel;
private boolean enteringFullScreen;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
context = this;
contentView = createView();
setContentView(contentView);
}
@Override
protected void onStop() {
if (videoView != null) {
if (videoView.isPlaying()) {
stopPlayback();
}
}
super.onStop();
}
private View createView() {
enteringFullScreen = false;
assetUri = this.getIntent().getStringExtra("com.widevine.demo.Path");
drm = new WidevineDrm(this);
drm.logBuffer.append("Asset Uri: " + assetUri + "\n");
drm.logBuffer.append("Drm Server: " + WidevineDrm.Settings.DRM_SERVER_URI + "\n");
drm.logBuffer.append("Device Id: " + WidevineDrm.Settings.DEVICE_ID + "\n");
drm.logBuffer.append("Portal Name: " + WidevineDrm.Settings.PORTAL_NAME + "\n");
// Set log update listener
WidevineDrm.WidevineDrmLogEventListener drmLogListener =
new WidevineDrm.WidevineDrmLogEventListener() {
public void logUpdated() {
updateLogs();
}
};
videoView = new FullScreenVideoView(this);
logs = new TextView(this);
drm.setLogListener(drmLogListener);
scrollView = new ScrollView(this);
scrollView.addView(logs);
// Set message handler for log events
hRefresh = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case REFRESH:
/* Refresh UI */
logs.setText(drm.logBuffer.toString());
scrollView.fullScroll(ScrollView.FOCUS_DOWN);
break;
}
}
};
updateLogs();
sidePanel = new LinearLayout(this);
sidePanel.setOrientation(LinearLayout.VERTICAL);
sidePanel.addView(scrollView, new LinearLayout.LayoutParams(300, 450));
LinearLayout.LayoutParams paramsSidePanel = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
paramsSidePanel.gravity = Gravity.CENTER;
sidePanel.addView(createButtons(), paramsSidePanel);
FrameLayout playerFrame = new FrameLayout(this);
playerFrame.addView(videoView, new FrameLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
FrameLayout.LayoutParams.MATCH_PARENT));
bgImage = new ClipImageView(this);
bgImage.setBackgroundDrawable(getResources().getDrawable(R.drawable.play_shield));
bgImage.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
startPlayback();
}
});
fullScreen = new Button(this);
fullScreen.setText(FULLSCREEN);
fullScreen.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
int currentPosition = videoView.getCurrentPosition();
videoView.setVisibility(View.INVISIBLE);
if (fullScreen.getText().equals(FULLSCREEN)) {
videoView.setFullScreen(true);
fullScreen.setText(EXIT_FULLSCREEN);
enteringFullScreen = true;
} else {
videoView.setFullScreen(false);
fullScreen.setText(FULLSCREEN);
}
videoView.setVisibility(View.VISIBLE);
stopPlayback();
startPlayback();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
videoView.seekTo(currentPosition);
}
});
playerFrame.addView(fullScreen, new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.WRAP_CONTENT,
FrameLayout.LayoutParams.WRAP_CONTENT));
fullScreen.setVisibility(View.INVISIBLE);
playerFrame.addView(bgImage, new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.WRAP_CONTENT,
FrameLayout.LayoutParams.WRAP_CONTENT));
main = new LinearLayout(this);
main.addView(playerFrame, new LinearLayout.LayoutParams(900,
LinearLayout.LayoutParams.FILL_PARENT, 1));
main.addView(sidePanel, new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.FILL_PARENT, 3));
return main;
}
private void startPlayback() {
playButton.setText(R.string.stop);
bgImage.setVisibility(View.GONE);
videoView.setVideoPath(assetUri);
videoView.setMediaController(new MediaController(context));
videoView.setOnErrorListener(new OnErrorListener() {
public boolean onError(MediaPlayer mp, int what, int extra) {
String message = "Unknown error";
switch (what) {
case MediaPlayer.MEDIA_ERROR_UNKNOWN:
message = "Unable to play media";
break;
case MediaPlayer.MEDIA_ERROR_SERVER_DIED:
message = "Server failed";
break;
case MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK:
message = "Invalid media";
break;
}
drm.logBuffer.append(message + "\n");
updateLogs();
bgImage.setVisibility(View.VISIBLE);
return false;
}
});
videoView.setOnCompletionListener(new OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
stopPlayback();
}
});
videoView.requestFocus();
videoView.start();
if (videoView.getFullScreen()) {
sidePanel.setVisibility(View.GONE);
} else {
sidePanel.setVisibility(View.VISIBLE);
}
fullScreen.setVisibility(View.VISIBLE);
videoView.setFullScreenDimensions(contentView.getRight() - contentView.getLeft(),
contentView.getBottom() - contentView.getTop());
}
private void stopPlayback() {
playButton.setText(R.string.play);
videoView.stopPlayback();
fullScreen.setVisibility(View.INVISIBLE);
bgImage.setVisibility(View.VISIBLE);
if (videoView.getFullScreen() && !enteringFullScreen) {
videoView.setVisibility(View.INVISIBLE);
videoView.setFullScreen(false);
videoView.setVisibility(View.VISIBLE);
sidePanel.setVisibility(View.VISIBLE);
fullScreen.setText(FULLSCREEN);
}
enteringFullScreen = false;
}
private View createButtons() {
playButton = new Button(this);
playButton.setText(R.string.play);
playButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Button b = (Button) v;
if (b.getText().equals(PLAY)) {
startPlayback();
} else {
stopPlayback();
}
}
});
Button rightsButton = new Button(this);
rightsButton.setText(R.string.acquire_rights);
rightsButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
drm.acquireRights(assetUri);
updateLogs();
}
});
Button removeButton = new Button(this);
removeButton.setText(R.string.remove_rights);
removeButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
drm.removeRights(assetUri);
updateLogs();
}
});
Button checkButton = new Button(this);
checkButton.setText(R.string.show_rights);
checkButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
drm.showRights(assetUri);
updateLogs();
}
});
Button checkConstraints = new Button(this);
checkConstraints.setText(R.string.constraints);
checkConstraints.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
drm.getConstraints(assetUri);
updateLogs();
}
});
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.FILL_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT, 1);
params.setMargins(0, 0, 0, 5);
LinearLayout buttonsLeft = new LinearLayout(this);
buttonsLeft.setOrientation(LinearLayout.VERTICAL);
buttonsLeft.addView(playButton, params);
buttonsLeft.addView(rightsButton, params);
buttonsLeft.addView(checkConstraints, params);
LinearLayout buttonsRight = new LinearLayout(this);
buttonsRight.setOrientation(LinearLayout.VERTICAL);
buttonsRight.addView(checkButton, params);
buttonsRight.addView(removeButton, params);
LinearLayout.LayoutParams paramsSides = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.FILL_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT, 1);
paramsSides.gravity = Gravity.BOTTOM;
LinearLayout buttons = new LinearLayout(this);
buttons.addView(buttonsLeft, paramsSides);
buttons.addView(buttonsRight, paramsSides);
return buttons;
}
private void updateLogs() {
hRefresh.sendEmptyMessage(REFRESH);
}
}

View File

@@ -0,0 +1,252 @@
/*
* (c)Copyright 2011 Widevine Technologies, Inc
*/
package com.widevine.demo;
import java.util.EventListener;
//import java.util.HashMap;
import java.util.Set;
import android.content.ContentValues;
import android.content.Context;
import android.drm.DrmErrorEvent;
import android.drm.DrmEvent;
import android.drm.DrmInfoEvent;
import android.drm.DrmInfoRequest;
import android.drm.DrmManagerClient;
import android.drm.DrmStore;
public class WidevineDrm {
interface WidevineDrmLogEventListener extends EventListener {
public void logUpdated();
}
private WidevineDrmLogEventListener logEventListener;
public StringBuffer logBuffer = new StringBuffer();
/**
* Drm Manager Configuration Methods
*/
public static class Settings {
public static String WIDEVINE_MIME_TYPE = "video/wvm";
public static String DRM_SERVER_URI = "https://wstfcps005.shibboleth.tv/widevine/cypherpc/cgi-bin/GetEMMs.cgi";
public static String DEVICE_ID = "device12345"; // use a unique device ID
public static String PORTAL_NAME = "OEM";
// test with a sizeable block of user data...
public static String USER_DATA = "01234567890123456789012345678901234567890123456789"
+ "01234567890123456789012345678901234567890123456789"
+ "01234567890123456789012345678901234567890123456789"
+ "01234567890123456789012345678901234567890123456789"
+ "01234567890123456789012345678901234567890123456789"
+ "01234567890123456789012345678901234567890123456789";
};
private DrmManagerClient mDrmManager;
// private Context mContext;
public WidevineDrm(Context context) {
// mContext = context;
mDrmManager = new DrmManagerClient(context);
mDrmManager.setOnInfoListener(new DrmManagerClient.OnInfoListener() {
// @Override
public void onInfo(DrmManagerClient client, DrmInfoEvent event) {
if (event.getType() == DrmInfoEvent.TYPE_RIGHTS_INSTALLED) {
logMessage("Rights installed\n");
}
}
});
mDrmManager.setOnEventListener(new DrmManagerClient.OnEventListener() {
public void onEvent(DrmManagerClient client, DrmEvent event) {
switch (event.getType()) {
case DrmEvent.TYPE_DRM_INFO_PROCESSED:
logMessage("Info Processed\n");
break;
}
}
});
mDrmManager.setOnErrorListener(new DrmManagerClient.OnErrorListener() {
public void onError(DrmManagerClient client, DrmErrorEvent event) {
switch (event.getType()) {
case DrmErrorEvent.TYPE_ALL_RIGHTS_REMOVED:
logMessage("Remove All Rights failed\n");
break;
case DrmErrorEvent.TYPE_DRM_INFO_PROCESSED:
logMessage("Info Processed failed\n");
break;
case DrmErrorEvent.TYPE_NO_INTERNET_CONNECTION:
logMessage("No Internet Connection\n");
break;
case DrmErrorEvent.TYPE_NOT_SUPPORTED:
logMessage("Not Supported\n");
break;
case DrmErrorEvent.TYPE_OUT_OF_MEMORY:
logMessage("Out of Memory\n");
break;
case DrmErrorEvent.TYPE_PROCESS_DRM_INFO_FAILED:
logMessage("Process DRM Info failed\n");
break;
case DrmErrorEvent.TYPE_REMOVE_ALL_RIGHTS_FAILED:
logMessage("Remove all rights\n");
break;
case DrmErrorEvent.TYPE_RIGHTS_NOT_INSTALLED:
logMessage("Rights not installed\n");
break;
case DrmErrorEvent.TYPE_RIGHTS_RENEWAL_NOT_ALLOWED:
logMessage("Rights renewal not allowed\n");
break;
}
}
});
}
public DrmInfoRequest getDrmInfoRequest(String assetUri) {
DrmInfoRequest rightsAcquisitionInfo;
rightsAcquisitionInfo = new DrmInfoRequest(DrmInfoRequest.TYPE_RIGHTS_ACQUISITION_INFO,
Settings.WIDEVINE_MIME_TYPE);
rightsAcquisitionInfo.put("WVDRMServerKey", Settings.DRM_SERVER_URI);
rightsAcquisitionInfo.put("WVAssetURIKey", assetUri);
rightsAcquisitionInfo.put("WVDeviceIDKey", Settings.DEVICE_ID);
rightsAcquisitionInfo.put("WVPortalKey", Settings.PORTAL_NAME);
rightsAcquisitionInfo.put("WVCAUserDataKey", Settings.USER_DATA);
return rightsAcquisitionInfo;
}
public int acquireRights(String assetUri) {
int rights = mDrmManager.acquireRights(getDrmInfoRequest(assetUri));
logMessage("acquireRights = " + rights + "\n");
return rights;
}
public int checkRightsStatus(String assetUri) {
// Need to use acquireDrmInfo prior to calling checkRightsStatus
mDrmManager.acquireDrmInfo(getDrmInfoRequest(assetUri));
int status = mDrmManager.checkRightsStatus(assetUri);
logMessage("checkRightsStatus = " + status + "\n");
return status;
}
public void getConstraints(String assetUri) {
// Need to use acquireDrmInfo prior to calling checkRightsStatus
mDrmManager.acquireDrmInfo(getDrmInfoRequest(assetUri));
ContentValues values = mDrmManager.getConstraints(assetUri, DrmStore.Action.PLAY);
logContentValues(values, "No Contraints");
}
public void showRights(String assetUri) {
logMessage("showRights\n");
// Need to use acquireDrmInfo prior to calling getConstraints
mDrmManager.acquireDrmInfo(getDrmInfoRequest(assetUri));
ContentValues values = mDrmManager.getConstraints(assetUri, DrmStore.Action.PLAY);
logContentValues(values, "No Rights");
}
private void logContentValues(ContentValues values, String defaultMessage) {
if (values != null) {
Set<String> keys = values.keySet();
for (String key : keys) {
if (key.toLowerCase().contains("time")) {
logMessage(key + " = " + SecondsToDHMS(values.getAsLong(key)) + "\n");
} else if (key.toLowerCase().contains("licensetype")) {
logMessage(key + " = " + licenseType(values.getAsInteger(key)) + "\n");
} else if (key.toLowerCase().contains("licensedresolution")) {
logMessage(key + " = " + licenseResolution(values.getAsInteger(key)) + "\n");
} else {
logMessage(key + " = " + values.get(key) + "\n");
}
}
} else {
logMessage(defaultMessage + "\n");
}
}
private static final long seconds_per_minute = 60;
private static final long seconds_per_hour = 60 * seconds_per_minute;
private static final long seconds_per_day = 24 * seconds_per_hour;
private String SecondsToDHMS(long seconds) {
int days = (int) (seconds / seconds_per_day);
seconds -= days * seconds_per_day;
int hours = (int) (seconds / seconds_per_hour);
seconds -= hours * seconds_per_hour;
int minutes = (int) (seconds / seconds_per_minute);
seconds -= minutes * seconds_per_minute;
return Integer.toString(days) + "d " + Integer.toString(hours) + "h "
+ Integer.toString(minutes) + "m " + Long.toString(seconds)
+ "s";
}
private String licenseType(int code) {
switch (code) {
case 1:
return "Streaming";
case 2:
return "Offline";
case 3:
return "Both";
default:
return "Unknown";
}
}
private String licenseResolution(int code) {
switch (code) {
case 1:
return "SD only";
case 2:
return "HD or SD content";
default:
return "Unknown";
}
}
public int removeRights(String assetUri) {
// Need to use acquireDrmInfo prior to calling removeRights
mDrmManager.acquireDrmInfo(getDrmInfoRequest(assetUri));
int removeStatus = mDrmManager.removeRights(assetUri);
logMessage("removeRights = " + removeStatus + "\n");
return removeStatus;
}
public int removeAllRights() {
int removeAllStatus = mDrmManager.removeAllRights();
logMessage("removeAllRights = " + removeAllStatus + "\n");
return removeAllStatus;
}
public void setLogListener(WidevineDrmLogEventListener logEventListener) {
this.logEventListener = logEventListener;
}
private void logMessage(String message) {
logBuffer.append(message);
if (logEventListener != null) {
logEventListener.logUpdated();
}
}
}

View File

@@ -0,0 +1,86 @@
/*
* (c)Copyright 2011 Widevine Technologies, Inc
*/
package com.widevine.demo;
import android.app.TabActivity;
import android.os.Bundle;
import android.widget.TabHost;
import android.content.Intent;
import android.content.SharedPreferences;
public class WidevineSamplePlayer extends TabActivity {
public static final String PREFS_NAME = "DrmPrefs";
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
WidevineDrm.Settings.DRM_SERVER_URI = settings.getString("drmServer",
WidevineDrm.Settings.DRM_SERVER_URI);
WidevineDrm.Settings.DEVICE_ID = settings.getString("deviceId",
WidevineDrm.Settings.DEVICE_ID);
WidevineDrm.Settings.PORTAL_NAME = settings.getString("portalId",
WidevineDrm.Settings.PORTAL_NAME);
SettingsActivity.CONTENT_PAGE = settings.getString("contentPage",
SettingsActivity.CONTENT_PAGE);
setContentView(R.layout.main);
TabHost tab = getTabHost();
// Setup Streaming tab
TabHost.TabSpec streamingTab = tab.newTabSpec("Streaming");
streamingTab.setIndicator("Streaming");
Intent streamingIntent = new Intent(this, StreamingActivity.class);
streamingTab.setContent(streamingIntent);
tab.addTab(streamingTab);
// Setup Down load tab
TabHost.TabSpec downloadTab = tab.newTabSpec("Downloads");
downloadTab.setIndicator("Downloads");
Intent downloadIntent = new Intent(this, DownloadActivity.class);
downloadTab.setContent(downloadIntent);
tab.addTab(downloadTab);
// Setup Settings tab
TabHost.TabSpec settingsTab = tab.newTabSpec("Settings");
settingsTab.setIndicator("Settings");
Intent settingsIntent = new Intent(this, SettingsActivity.class);
settingsTab.setContent(settingsIntent);
tab.addTab(settingsTab);
}
@Override
protected void onStop() {
super.onStop();
// We need an Editor object to make preference changes.
// All objects are from android.context.Context
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putString("drmServer", WidevineDrm.Settings.DRM_SERVER_URI);
editor.putString("deviceId", WidevineDrm.Settings.DEVICE_ID);
editor.putString("portalId", WidevineDrm.Settings.PORTAL_NAME);
editor.putString("contentPage", SettingsActivity.CONTENT_PAGE);
// Commit the edits!
editor.commit();
}
}

Binary file not shown.