From 829f9ad8c06070038cdef24e5fac76a8a16f841b Mon Sep 17 00:00:00 2001 From: Paramananda Pradhan Date: Sun, 14 Dec 2014 17:27:31 +0530 Subject: Gallery2: Make Gallery2 support OMADRM feature - Make Gallery2 can recognize and consume DRM images and videos. Change-Id: I1655d295bcec31b5760c2c86c06f815cf6ed57ee --- src/com/android/gallery3d/app/AlbumPage.java | 112 ++++++++++++- src/com/android/gallery3d/app/AlbumSetPage.java | 82 ++++++++++ src/com/android/gallery3d/app/GalleryActivity.java | 85 +++++++++- src/com/android/gallery3d/app/MovieActivity.java | 36 +++++ src/com/android/gallery3d/app/PhotoPage.java | 179 ++++++++++++++++++++- src/com/android/gallery3d/app/Wallpaper.java | 1 + src/com/android/gallery3d/data/DecodeUtils.java | 22 ++- .../android/gallery3d/data/ImageCacheRequest.java | 34 +++- src/com/android/gallery3d/data/LocalImage.java | 38 ++++- src/com/android/gallery3d/data/LocalVideo.java | 31 +++- src/com/android/gallery3d/data/MediaObject.java | 13 +- src/com/android/gallery3d/data/UriImage.java | 56 ++++++- .../gallery3d/filtershow/crop/CropActivity.java | 6 + .../gallery3d/gadget/PhotoAppWidgetProvider.java | 2 +- .../gallery3d/gadget/WidgetClickHandler.java | 2 + .../gallery3d/glrenderer/NinePatchTexture.java | 2 +- .../gallery3d/glrenderer/ResourceTexture.java | 13 +- .../android/gallery3d/ui/AbstractSlotRenderer.java | 16 ++ .../gallery3d/ui/AlbumSetSlidingWindow.java | 14 ++ .../android/gallery3d/ui/AlbumSetSlotRenderer.java | 5 +- .../android/gallery3d/ui/AlbumSlidingWindow.java | 13 ++ .../android/gallery3d/ui/AlbumSlotRenderer.java | 3 + src/com/android/gallery3d/ui/MenuExecutor.java | 36 ++++- 23 files changed, 766 insertions(+), 35 deletions(-) (limited to 'src') diff --git a/src/com/android/gallery3d/app/AlbumPage.java b/src/com/android/gallery3d/app/AlbumPage.java index 7e2f5f9e4..436ecbb8b 100644 --- a/src/com/android/gallery3d/app/AlbumPage.java +++ b/src/com/android/gallery3d/app/AlbumPage.java @@ -18,13 +18,24 @@ package com.android.gallery3d.app; import android.app.Activity; import android.content.Context; +import android.content.ContentValues; import android.content.Intent; +import android.database.Cursor; +import android.drm.DrmManagerClient; +import android.drm.DrmRights; +import android.drm.DrmStore.Action; +import android.drm.DrmStore.DrmDeliveryType; +import android.drm.DrmStore.RightsStatus; +import android.graphics.BitmapFactory; +import android.graphics.BitmapFactory.Options; import android.graphics.Rect; import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.provider.MediaStore; +import android.provider.MediaStore.Video.VideoColumns; +import android.text.TextUtils; import android.text.TextUtils; import android.view.HapticFeedbackConstants; import android.view.Menu; @@ -36,6 +47,7 @@ import android.widget.Toast; import com.android.gallery3d.R; import com.android.gallery3d.common.Utils; import com.android.gallery3d.data.DataManager; +import com.android.gallery3d.data.LocalMediaItem; import com.android.gallery3d.data.MediaDetails; import com.android.gallery3d.data.MediaItem; import com.android.gallery3d.data.MediaObject; @@ -62,12 +74,20 @@ import com.android.gallery3d.util.GalleryUtils; import com.android.gallery3d.util.MediaSetUtils; import java.util.Locale; +import java.io.File; +import java.io.FileDescriptor; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.Random; + public class AlbumPage extends ActivityState implements GalleryActionBar.ClusterRunner, SelectionManager.SelectionListener, MediaSet.SyncListener, GalleryActionBar.OnAlbumModeSelectedListener { @SuppressWarnings("unused") private static final String TAG = "AlbumPage"; + public static final String BUY_LICENSE = "android.drmservice.intent.action.BUY_LICENSE"; + public static final String KEY_MEDIA_PATH = "media-path"; public static final String KEY_PARENT_MEDIA_PATH = "parent-media-path"; public static final String KEY_SET_CENTER = "set-center"; @@ -101,7 +121,8 @@ public class AlbumPage extends ActivityState implements GalleryActionBar.Cluster private boolean mGetContent; private boolean mShowClusterMenu; - + private boolean mIsWallpaper; + private boolean mIsContactPhoto; private ActionModeHandler mActionModeHandler; private int mFocusIndex = 0; private DetailsHelper mDetailsHelper; @@ -322,6 +343,69 @@ public class AlbumPage extends ActivityState implements GalleryActionBar.Cluster transitions.put(PhotoPage.KEY_INDEX_HINT, slotIndex); onBackPressed(); } else { + Context context = (Context) mActivity; + Uri uri = item.getContentUri(); + Log.d(TAG, "pickPhoto:uri=" + item.getContentUri()); + String path = null; + String scheme = uri.getScheme(); + if ("file".equals(scheme)) { + path = uri.getPath(); + } else { + Cursor cursor = null; + try { + cursor = context.getContentResolver().query(uri, + new String[] {VideoColumns.DATA}, null, null, null); + if (cursor != null && cursor.moveToNext()) { + path = cursor.getString(0); + } + } catch (Throwable t) { + Log.d(TAG, "cannot get path from: " + uri); + } finally { + if (cursor != null) cursor.close(); + } + } + + Log.d(TAG, "pickPhoto:path = " + path); + if (path != null && (path.endsWith(".dcf") || path.endsWith(".dm"))) { + DrmManagerClient drmClient = new DrmManagerClient(context); + path = path.replace("/storage/emulated/0", "/storage/emulated/legacy"); + int status = -1; + Log.d(TAG, "pickPhoto:item type = " + Integer.toString(item.getMediaType())); + + if (item.getMediaType() == MediaObject.MEDIA_TYPE_IMAGE) { + status = drmClient.checkRightsStatus(path, Action.DISPLAY); + } else { + status = drmClient.checkRightsStatus(path, Action.PLAY); + } + Log.d(TAG, "pickPhoto:status fron drmClient.checkRightsStatus is " + + Integer.toString(status)); + + ContentValues values = drmClient.getMetadata(path); + + // This hack is added to work FL. It will remove after the sdcard permission issue solved + status = RightsStatus.RIGHTS_VALID; + + if (RightsStatus.RIGHTS_VALID!= status) { + String address = values.getAsString("Rights-Issuer"); + Log.d(TAG, "pickPhoto:address = " + address); + Intent intent = new Intent(BUY_LICENSE); + intent.putExtra("DRM_FILE_PATH", address); + context.sendBroadcast(intent); + return; + } + + int drmType = values.getAsInteger("DRM-TYPE"); + Log.d(TAG, "onSingleTapUp:drm-type = " + Integer.toString(drmType)); + if (drmType > DrmDeliveryType.FORWARD_LOCK) { + if (item.getMediaType() == MediaObject.MEDIA_TYPE_IMAGE) { + item.setConsumeRights(true); + } + Toast.makeText(context, R.string.action_consumes_rights, + Toast.LENGTH_LONG).show(); + } + if (drmClient != null) drmClient.release(); + } + // Get into the PhotoPage. // mAlbumView.savePositions(PositionRepository.getInstance(mActivity)); Bundle data = new Bundle(); @@ -355,6 +439,7 @@ public class AlbumPage extends ActivityState implements GalleryActionBar.Cluster Activity activity = mActivity; if (mData.getString(GalleryActivity.EXTRA_CROP) != null) { Uri uri = dm.getContentUri(item.getPath()); + Intent intent = new Intent(CropActivity.CROP_ACTION, uri) .addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT) .putExtras(getData()); @@ -363,6 +448,29 @@ public class AlbumPage extends ActivityState implements GalleryActionBar.Cluster } activity.startActivity(intent); activity.finish(); + } else if (mIsWallpaper != true && mIsContactPhoto != true) { + String path = null; + if (item instanceof LocalMediaItem) { + path = ((LocalMediaItem)item).filePath; + } + if (path != null && (path.endsWith(".dcf") || path.endsWith(".dm"))) { + DrmManagerClient drmClient = new DrmManagerClient((Context) mActivity); + path = path.replace("/storage/emulated/0", "/storage/emulated/legacy"); + ContentValues values = drmClient.getMetadata(path); + int drmType = values.getAsInteger("DRM-TYPE"); + Log.d(TAG, "onGetContent:DRM-TYPE = " + Integer.toString(drmType)); + if (drmType == DrmDeliveryType.SEPARATE_DELIVERY) { + activity.setResult(Activity.RESULT_OK, new Intent(null, item.getContentUri())); + } else { + Toast.makeText((Context) mActivity, R.string.no_permission_for_drm, + Toast.LENGTH_LONG).show(); + } + if (drmClient != null) drmClient.release(); + } else { + activity.setResult(Activity.RESULT_OK, + new Intent(null, item.getContentUri())); + } + activity.finish(); } else { Intent intent = new Intent(null, item.getContentUri()) .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); @@ -405,6 +513,8 @@ public class AlbumPage extends ActivityState implements GalleryActionBar.Cluster initializeViews(); initializeData(data); mGetContent = data.getBoolean(GalleryActivity.KEY_GET_CONTENT, false); + mIsWallpaper = data.getBoolean("com.android.gallery3d.IsWallpaper", false); + mIsContactPhoto = data.getBoolean("isContactPhoto", false); mShowClusterMenu = data.getBoolean(KEY_SHOW_CLUSTER_MENU, false); mDetailsSource = new MyDetailsSource(); Context context = mActivity.getAndroidContext(); diff --git a/src/com/android/gallery3d/app/AlbumSetPage.java b/src/com/android/gallery3d/app/AlbumSetPage.java index c09b91f6e..8db74f5dd 100644 --- a/src/com/android/gallery3d/app/AlbumSetPage.java +++ b/src/com/android/gallery3d/app/AlbumSetPage.java @@ -21,12 +21,21 @@ package com.android.gallery3d.app; import android.app.Activity; import android.content.Context; +import android.content.ContentValues; import android.content.Intent; +import android.database.Cursor; +import android.drm.DrmManagerClient; +import android.drm.DrmRights; +import android.drm.DrmStore.Action; +import android.drm.DrmStore.DrmDeliveryType; +import android.drm.DrmStore.RightsStatus; import android.graphics.Rect; import android.net.Uri; +import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.os.Message; +import android.provider.MediaStore.Video.VideoColumns; import android.view.HapticFeedbackConstants; import android.view.Menu; import android.view.MenuInflater; @@ -63,8 +72,13 @@ import com.android.gallery3d.util.Future; import com.android.gallery3d.util.GalleryUtils; import com.android.gallery3d.util.HelpUtils; +import java.io.File; +import java.io.FileDescriptor; +import java.io.FileInputStream; +import java.io.IOException; import java.lang.ref.WeakReference; import java.util.ArrayList; +import java.util.Random; public class AlbumSetPage extends ActivityState implements SelectionManager.SelectionListener, GalleryActionBar.ClusterRunner, @@ -74,6 +88,8 @@ public class AlbumSetPage extends ActivityState implements private static final int MSG_PICK_ALBUM = 1; + public static final String BUY_LICENSE = "android.drmservice.intent.action.BUY_LICENSE"; + public static final String KEY_MEDIA_PATH = "media-path"; public static final String KEY_SET_TITLE = "set-title"; public static final String KEY_SET_SUBTITLE = "set-subtitle"; @@ -242,6 +258,72 @@ public class AlbumSetPage extends ActivityState implements if (!mIsActive) return; MediaSet targetSet = mAlbumSetDataAdapter.getMediaSet(slotIndex); + if (targetSet.getTotalMediaItemCount() == 1) { + MediaItem item = null; + item = targetSet.getCoverMediaItem(); + Uri uri = item.getContentUri(); + Context context = (Context) mActivity; + + Log.d(TAG, "pickAlbum:uri=" + item.getContentUri()); + String path = null; + String scheme = uri.getScheme(); + if ("file".equals(scheme)) { + path = uri.getPath(); + } else { + Cursor cursor = null; + try { + cursor = context.getContentResolver().query(uri, + new String[] {VideoColumns.DATA}, null, null, null); + if (cursor != null && cursor.moveToNext()) { + path = cursor.getString(0); + } + } catch (Throwable t) { + Log.w(TAG, "cannot get path from: " + uri); + } finally { + if (cursor != null) cursor.close(); + } + } + + Log.d(TAG, "pickAlbum:path = " + path); + if (path != null && (path.endsWith(".dcf") || path.endsWith(".dm"))) { + DrmManagerClient drmClient = new DrmManagerClient(context); + int status = -1; + path = path.replace("/storage/emulated/0", "/storage/emulated/legacy"); + Log.d(TAG, "pickAlbum:item type = " + Integer.toString(item.getMediaType())); + if (item.getMediaType() == MediaObject.MEDIA_TYPE_IMAGE) { + status = drmClient.checkRightsStatus(path, Action.DISPLAY); + } else { + status = drmClient.checkRightsStatus(path, Action.PLAY); + } + Log.d(TAG, "pickAlbum:status fron drmClient.checkRightsStatus is " + + Integer.toString(status)); + + ContentValues values = drmClient.getMetadata(path); + + // This hack is added to work FL. It will remove after the sdcard permission issue solved + status = RightsStatus.RIGHTS_VALID; + + if (RightsStatus.RIGHTS_VALID != status) { + String address = values.getAsString("Rights-Issuer"); + Log.d(TAG, "pickAlbum:address = " + address); + Intent intent = new Intent(BUY_LICENSE); + intent.putExtra("DRM_FILE_PATH", address); + context.sendBroadcast(intent); + return; + } + + int drmType = values.getAsInteger("DRM-TYPE"); + Log.d(TAG, "pickAlbum:drm-type = " + Integer.toString(drmType)); + if (drmType > DrmDeliveryType.FORWARD_LOCK) { + if (item.getMediaType() == MediaObject.MEDIA_TYPE_IMAGE) { + item.setConsumeRights(true); + } + Toast.makeText(context, R.string.action_consumes_rights, + Toast.LENGTH_LONG).show(); + } + if (drmClient != null) drmClient.release(); + } + } if (targetSet == null) return; // Content is dirty, we shall reload soon if (targetSet.getTotalMediaItemCount() == 0) { showEmptyAlbumToast(Toast.LENGTH_SHORT); diff --git a/src/com/android/gallery3d/app/GalleryActivity.java b/src/com/android/gallery3d/app/GalleryActivity.java index 1be5e73c8..061c783c0 100644 --- a/src/com/android/gallery3d/app/GalleryActivity.java +++ b/src/com/android/gallery3d/app/GalleryActivity.java @@ -18,11 +18,18 @@ package com.android.gallery3d.app; import android.app.Dialog; import android.content.ContentResolver; +import android.content.ContentValues; import android.content.DialogInterface; import android.content.DialogInterface.OnCancelListener; import android.content.Intent; +import android.database.Cursor; +import android.drm.DrmManagerClient; +import android.drm.DrmStore.Action; +import android.drm.DrmStore.DrmDeliveryType; +import android.drm.DrmStore.RightsStatus; import android.net.Uri; import android.os.Bundle; +import android.provider.MediaStore.Video.VideoColumns; import android.view.InputDevice; import android.view.MotionEvent; import android.view.View; @@ -34,12 +41,14 @@ import com.android.gallery3d.R; import com.android.gallery3d.common.Utils; import com.android.gallery3d.data.DataManager; import com.android.gallery3d.data.MediaItem; +import com.android.gallery3d.data.MediaObject; import com.android.gallery3d.data.MediaSet; import com.android.gallery3d.data.Path; import com.android.gallery3d.picasasource.PicasaSource; import com.android.gallery3d.util.GalleryUtils; public final class GalleryActivity extends AbstractGalleryActivity implements OnCancelListener { + public static final String BUY_LICENSE = "android.drmservice.intent.action.BUY_LICENSE"; public static final String EXTRA_SLIDESHOW = "slideshow"; public static final String EXTRA_DREAM = "dream"; public static final String EXTRA_CROP = "crop"; @@ -203,7 +212,81 @@ public final class GalleryActivity extends AbstractGalleryActivity implements On startDefaultPage(); } } else { - Path itemPath = dm.findPathByUri(uri, contentType); + Path itemPath = null; + String imagePath = null; + String scheme = uri.getScheme(); + if ("file".equals(scheme)) { + imagePath = uri.getPath(); + } else { + Cursor cursor = null; + try { + cursor = this.getContentResolver().query(uri, + new String[] {VideoColumns.DATA}, null, null, null); + if (cursor != null && cursor.moveToNext()) { + imagePath = cursor.getString(0); + } + } catch (Throwable t) { + Log.d(TAG, "cannot get path from: " + uri); + } finally { + if (cursor != null) cursor.close(); + } + } + String mime_Type = intent.getType(); + if (imagePath != null + && (imagePath.endsWith(".dcf") || imagePath.endsWith(".dm")) + && "*/*".equals(mime_Type)) { + imagePath = imagePath.replace("/storage/emulated/0", "/storage/emulated/legacy"); + DrmManagerClient drmClient = new DrmManagerClient(this); + mime_Type = drmClient.getOriginalMimeType(imagePath); + if (drmClient != null) drmClient.release(); + } + + Log.d(TAG, "DRM mime_Type==" + mime_Type); + itemPath = getDataManager().findPathByUri(uri, mime_Type); + Log.d(TAG, "itemPath=" + itemPath); + // If item path not correct, just finish starting the gallery + if (itemPath == null) { + finish(); + return; + } + + Log.d(TAG,"imagePath=" + imagePath); + if (intent.getBooleanExtra("WidgetClick", false) == true) { + DrmManagerClient drmClient = new DrmManagerClient(this); + + // This hack is added to work FL. It will remove after the sdcard permission issue solved + int status = drmClient.checkRightsStatus(imagePath, Action.DISPLAY); + status = RightsStatus.RIGHTS_VALID; + + if (RightsStatus.RIGHTS_VALID != status) { + ContentValues values = drmClient.getMetadata(imagePath); + String address = values.getAsString("Rights-Issuer"); + Intent buyIntent = new Intent(BUY_LICENSE); + buyIntent.putExtra("DRM_FILE_PATH", address); + sendBroadcast(buyIntent); + Log.d(TAG, "startViewAction:WidgetClick, intent sent"); + } + if (drmClient != null) drmClient.release(); + } + + if (imagePath != null + && (imagePath.endsWith(".dcf") || imagePath.endsWith(".dm"))) { + DrmManagerClient drmClient = new DrmManagerClient(this); + imagePath = imagePath.replace("/storage/emulated/0", "/storage/emulated/legacy"); + ContentValues values = drmClient.getMetadata(imagePath); + int drmType = values.getAsInteger("DRM-TYPE"); + if (drmType > DrmDeliveryType.FORWARD_LOCK) { + MediaItem mediaItem = (MediaItem) getDataManager() + .getMediaObject(itemPath); + if (mediaItem.getMediaType() == MediaObject.MEDIA_TYPE_IMAGE) { + mediaItem.setConsumeRights(true); + } + Toast.makeText(this, R.string.action_consumes_rights, + Toast.LENGTH_LONG).show(); + } + if (drmClient != null) drmClient.release(); + } + Path albumPath = dm.getDefaultSetOf(itemPath); data.putString(PhotoPage.KEY_MEDIA_ITEM_PATH, itemPath.toString()); diff --git a/src/com/android/gallery3d/app/MovieActivity.java b/src/com/android/gallery3d/app/MovieActivity.java index 275b04ab3..c316a7846 100644 --- a/src/com/android/gallery3d/app/MovieActivity.java +++ b/src/com/android/gallery3d/app/MovieActivity.java @@ -27,6 +27,9 @@ import android.bluetooth.BluetoothDevice; import android.content.AsyncQueryHandler; import android.content.BroadcastReceiver; import android.content.ContentResolver; +import android.content.ContentValues; +import android.content.Context; +import android.content.DialogInterface; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; @@ -35,6 +38,8 @@ import android.content.res.Configuration; import android.content.SharedPreferences; import android.content.pm.ActivityInfo; import android.database.Cursor; +import android.drm.DrmManagerClient; +import android.drm.DrmStore.DrmDeliveryType; import android.graphics.Bitmap; import android.graphics.drawable.BitmapDrawable; import android.media.AudioManager; @@ -48,6 +53,7 @@ import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.provider.MediaStore; +import android.provider.MediaStore.Video.VideoColumns; import android.provider.OpenableColumns; import android.view.Gravity; import android.view.KeyEvent; @@ -306,6 +312,36 @@ public class MovieActivity extends Activity { @Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); + String path = null; + String scheme = mUri.getScheme(); + if ("file".equals(scheme)) { + path = mUri.getPath(); + } else { + Cursor cursor = null; + try { + cursor = getContentResolver().query(mUri, + new String[] {VideoColumns.DATA}, null, null, null); + if (cursor != null && cursor.moveToNext()) { + path = cursor.getString(0); + } + } catch (Throwable t) { + Log.d(TAG, "cannot get path from: " + mUri); + } finally { + if (cursor != null) cursor.close(); + } + } + Log.d(TAG, "onCreateOptionsMenu= " + path); + if ((path != null) && ((path.endsWith(".dcf") || path.endsWith(".dm")))) { + DrmManagerClient drmClient = new DrmManagerClient(this); + ContentValues values = drmClient.getMetadata(path); + int drmType = values.getAsInteger("DRM-TYPE"); + Log.d(TAG, "onCreateOptionsMenu:DRM-TYPE = " + Integer.toString(drmType)); + if (drmType != DrmDeliveryType.SEPARATE_DELIVERY) { + return true; + } + if (drmClient != null) drmClient.release(); + } + getMenuInflater().inflate(R.menu.movie, menu); MenuItem shareMenu = menu.findItem(R.id.action_share); ShareActionProvider provider = (ShareActionProvider) shareMenu.getActionProvider(); diff --git a/src/com/android/gallery3d/app/PhotoPage.java b/src/com/android/gallery3d/app/PhotoPage.java index dd27f2689..b5a4d5640 100755 --- a/src/com/android/gallery3d/app/PhotoPage.java +++ b/src/com/android/gallery3d/app/PhotoPage.java @@ -1,4 +1,4 @@ -/* +/** * Copyright (C) 2010 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -20,10 +20,18 @@ import android.annotation.TargetApi; import android.app.ActionBar.OnMenuVisibilityListener; import android.app.Activity; import android.content.ActivityNotFoundException; +import android.content.ContentValues; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.content.res.Configuration; +import android.database.Cursor; +import android.drm.DrmManagerClient; +import android.drm.DrmStore.Action; +import android.drm.DrmStore.DrmDeliveryType; +import android.drm.DrmStore.RightsStatus; +import android.graphics.BitmapFactory; +import android.graphics.BitmapFactory.Options; import android.graphics.Rect; import android.media.MediaFile; import android.net.Uri; @@ -34,6 +42,8 @@ import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.os.SystemClock; +import android.provider.MediaStore; +import android.provider.MediaStore.Video.VideoColumns; import android.text.TextUtils; import android.view.Menu; import android.view.MenuItem; @@ -44,6 +54,7 @@ import android.widget.Toast; import com.android.gallery3d.R; import com.android.gallery3d.common.ApiHelper; +import com.android.gallery3d.common.Utils; import com.android.gallery3d.data.ComboAlbum; import com.android.gallery3d.data.DataManager; import com.android.gallery3d.data.FilterDeleteSet; @@ -76,6 +87,11 @@ import com.android.gallery3d.util.GalleryUtils; import com.android.gallery3d.util.UsageStatistics; import com.android.gallery3d.util.ViewGifImage; +import java.io.File; +import java.io.FileDescriptor; +import java.io.FileInputStream; +import java.io.IOException; + import java.util.ArrayList; import java.util.Locale; @@ -84,6 +100,8 @@ public abstract class PhotoPage extends ActivityState implements PhotoPageBottomControls.Delegate, GalleryActionBar.OnAlbumModeSelectedListener { private static final String TAG = "PhotoPage"; + public static final String BUY_LICENSE = "android.drmservice.intent.action.BUY_LICENSE"; + private static final int MSG_HIDE_BARS = 1; private static final int MSG_ON_FULL_SCREEN_CHANGED = 4; private static final int MSG_UPDATE_ACTION_BAR = 5; @@ -377,8 +395,9 @@ public abstract class PhotoPage extends ActivityState implements panoramaIntent = createSharePanoramaIntent(contentUri); } Intent shareIntent = createShareIntent(mCurrentPhoto); - - mActionBar.setShareIntents(panoramaIntent, shareIntent, PhotoPage.this); + if (shareIntent != null) { + mActionBar.setShareIntents(panoramaIntent, shareIntent, PhotoPage.this); + } setNfcBeamPushUri(contentUri); } break; @@ -571,6 +590,16 @@ public abstract class PhotoPage extends ActivityState implements PhotoPage.this); } } + MediaItem item = mModel.getMediaItem(0); + if (item != null + && item.getMediaType() == MediaObject.MEDIA_TYPE_IMAGE + && item.getConsumeRights() == true) { + Log.d(TAG, "onDestroy,consume rights = true"); + item.setConsumeRights(false); + Uri uri = item.getContentUri(); + Log.d(TAG, "onDestroy:uri=" + uri); + consumeRights(uri); + } } @Override @@ -610,6 +639,40 @@ public abstract class PhotoPage extends ActivityState implements }); } + private void consumeRights(Uri uri) { + Log.d(TAG, "consumeRights:uri=" + uri); + String filepath = null; + String scheme = uri.getScheme(); + if ("file".equals(scheme)) { + filepath = uri.getPath(); + } else { + Cursor cursor = null; + try { + cursor = mActivity.getContentResolver().query(uri, + new String[] {VideoColumns.DATA}, null, null, null); + if (cursor != null && cursor.moveToNext()) { + filepath = cursor.getString(0); + } + } catch (Throwable t) { + Log.w(TAG, "cannot get path from: " + uri); + } finally { + if (cursor != null) cursor.close(); + } + } + Options options = new Options(); + FileInputStream fis = null; + try { + fis = new FileInputStream(new File(filepath)); + FileDescriptor fd = fis.getFD(); + Log.d(TAG, "onLoadingFinished:calling decodeFileDescriptor with true"); + BitmapFactory.decodeFileDescriptor(fd, new Rect(), options, true); + } catch(IOException e) { + Log.w(TAG, "IOException"); + } finally { + Utils.closeSilently(fis); + } + } + @Override public void onPictureCenter(boolean isCamera) { isCamera = isCamera || (mHasCameraScreennailOrPlaceholder && mAppBridge == null); @@ -683,8 +746,42 @@ public abstract class PhotoPage extends ActivityState implements mNfcPushUris[0] = uri; } - private static Intent createShareIntent(MediaObject mediaObject) { + private Intent createShareIntent(MediaObject mediaObject) { int type = mediaObject.getMediaType(); + Uri uri = mediaObject.getContentUri(); + Log.d(TAG, "updateShareURI:uri:" + uri); + String filepath = null; + String scheme = uri.getScheme(); + if ("file".equals(scheme)) { + filepath = uri.getPath(); + } else { + Cursor cursor = null; + try { + cursor = mApplication.getContentResolver().query(uri, + new String[] {VideoColumns.DATA}, null, null, null); + if (cursor != null && cursor.moveToNext()) { + filepath = cursor.getString(0); + } + } catch (Throwable t) { + Log.w(TAG, "cannot get path from: " + uri); + } finally { + if (cursor != null) cursor.close(); + } + } + + if (filepath != null && filepath.endsWith(".dcf")) { + DrmManagerClient drmClient = new DrmManagerClient(mActivity.getAndroidContext()); + filepath = filepath.replace("/storage/emulated/0", "/storage/emulated/legacy"); + ContentValues values = drmClient.getMetadata(filepath); + int drmType = values.getAsInteger("DRM-TYPE"); + Log.d(TAG, "updateShareURI:drmType returned= " + Integer.toString(drmType) + + " for path= " + filepath); + if (drmType != DrmDeliveryType.SEPARATE_DELIVERY) { + return null; + } + if (drmClient != null) drmClient.release(); + } + return new Intent(Intent.ACTION_SEND) .setType(MenuExecutor.getMimeType(type)) .putExtra(Intent.EXTRA_STREAM, mediaObject.getContentUri()) @@ -1157,6 +1254,34 @@ public abstract class PhotoPage extends ActivityState implements mSelectionManager.toggle(path); mMenuExecutor.onMenuClicked(item, confirmMsg, mConfirmDialogListener); return true; + case R.id.action_drm_info: + Uri uri = manager.getContentUri(path); + Log.d(TAG, "executeuri:" + uri); + String filepath = null; + String scheme = uri.getScheme(); + if ("file".equals(scheme)) { + filepath = uri.getPath(); + } else { + Cursor cursor = null; + try { + cursor = mActivity.getAndroidContext().getContentResolver().query(uri, + new String[] {VideoColumns.DATA}, null, null, null); + if (cursor != null && cursor.moveToNext()) { + filepath = cursor.getString(0); + } + } catch (Throwable t) { + Log.w(TAG, "cannot get path from: " + uri); + } finally { + if (cursor != null) cursor.close(); + } + } + filepath = filepath.replace("/storage/emulated/0", "/storage/emulated/legacy"); + Intent drmintent = new Intent("android.drmservice.intent.action.SHOW_PROPERTIES"); + drmintent.putExtra("DRM_FILE_PATH", filepath); + drmintent.putExtra("DRM_TYPE", "OMAV1"); + Log.d(TAG,"-----filepath===" + path); + mActivity.getAndroidContext().sendBroadcast(drmintent); + return true; default : return false; } @@ -1292,6 +1417,41 @@ public abstract class PhotoPage extends ActivityState implements public void playVideo(Activity activity, Uri uri, String title) { try { + String scheme = uri.getScheme(); + Log.d(TAG, "playVideo:uri= " + uri); + String path = null; + if (scheme.equals("content")) { + Cursor c = activity.getContentResolver().query(uri, + new String[] { MediaStore.Images.ImageColumns.DATA }, null, null, null); + if (c != null && c.getCount() > 0) { + c.moveToFirst(); + path = c.getString(c.getColumnIndex(MediaStore.Images.ImageColumns.DATA)); + Log.d(TAG, "playVideo:path= " + path); + } + if (c != null) c.close(); + } else { + path = uri.getPath(); + } + if (path.endsWith(".dcf")) { + DrmManagerClient drmClient = new DrmManagerClient(activity); + path = path.replace("/storage/emulated/0", "/storage/emulated/legacy"); + + // This hack is added to work FL. It will remove after the sdcard permission issue solved + int status = drmClient.checkRightsStatus(path, Action.PLAY); + status = RightsStatus.RIGHTS_VALID; + + if (RightsStatus.RIGHTS_VALID != status) { + ContentValues values = drmClient.getMetadata(path); + String address = values.getAsString("Rights-Issuer"); + Log.d(TAG, "playVideo, address= " + address); + Intent intent = new Intent(BUY_LICENSE); + intent.putExtra("DRM_FILE_PATH", address); + activity.sendBroadcast(intent); + return; + } + if (drmClient != null) drmClient.release(); + } + Intent intent = new Intent(Intent.ACTION_VIEW) .setDataAndType(uri, "video/*") .putExtra(Intent.EXTRA_TITLE, title) @@ -1396,6 +1556,17 @@ public abstract class PhotoPage extends ActivityState implements @Override public void onCurrentImageUpdated() { + if (mSetPathString == null) { + MediaItem item = mModel.getMediaItem(0); + if (item.getMediaType() == MediaObject.MEDIA_TYPE_IMAGE + && item.getConsumeRights() == true) { + Log.d(TAG, "onCurrentImageUpdated,consume rights = true"); + item.setConsumeRights(false); + Uri uri = item.getContentUri(); + Log.d(TAG, "onCurrentImageUpdated:uri=" + uri); + consumeRights(uri); + } + } mActivity.getGLRoot().unfreeze(); } diff --git a/src/com/android/gallery3d/app/Wallpaper.java b/src/com/android/gallery3d/app/Wallpaper.java index 5c19d9016..f9bbc1301 100644 --- a/src/com/android/gallery3d/app/Wallpaper.java +++ b/src/com/android/gallery3d/app/Wallpaper.java @@ -97,6 +97,7 @@ public class Wallpaper extends Activity { Intent request = new Intent(Intent.ACTION_GET_CONTENT) .setClass(this, DialogPicker.class) .setType(IMAGE_TYPE); + request.putExtra("com.android.gallery3d.IsWallpaper", true); startActivityForResult(request, STATE_PHOTO_PICKED); return; } diff --git a/src/com/android/gallery3d/data/DecodeUtils.java b/src/com/android/gallery3d/data/DecodeUtils.java index 825c4bbea..12405184c 100644 --- a/src/com/android/gallery3d/data/DecodeUtils.java +++ b/src/com/android/gallery3d/data/DecodeUtils.java @@ -87,7 +87,7 @@ public class DecodeUtils { jc.setCancelListener(new DecodeCanceller(options)); setOptionsMutable(options); return ensureGLCompatibleBitmap( - BitmapFactory.decodeByteArray(bytes, offset, length, options)); + BitmapFactory.decodeByteArray(bytes, offset, length, options, false)); } public static void decodeBounds(JobContext jc, byte[] bytes, int offset, @@ -95,7 +95,7 @@ public class DecodeUtils { Utils.assertTrue(options != null); options.inJustDecodeBounds = true; jc.setCancelListener(new DecodeCanceller(options)); - BitmapFactory.decodeByteArray(bytes, offset, length, options); + BitmapFactory.decodeByteArray(bytes, offset, length, options, false); options.inJustDecodeBounds = false; } @@ -120,7 +120,7 @@ public class DecodeUtils { jc.setCancelListener(new DecodeCanceller(options)); options.inJustDecodeBounds = true; - BitmapFactory.decodeFileDescriptor(fd, null, options); + BitmapFactory.decodeFileDescriptor(fd, null, options, false); if (jc.isCancelled()) return null; int w = options.outWidth; @@ -148,7 +148,7 @@ public class DecodeUtils { options.inJustDecodeBounds = false; setOptionsMutable(options); - Bitmap result = BitmapFactory.decodeFileDescriptor(fd, null, options); + Bitmap result = BitmapFactory.decodeFileDescriptor(fd, null, options, false); if (result == null) return null; // We need to resize down if the decoder does not support inSampleSize @@ -174,7 +174,7 @@ public class DecodeUtils { jc.setCancelListener(new DecodeCanceller(options)); options.inJustDecodeBounds = true; - BitmapFactory.decodeByteArray(data, 0, data.length, options); + BitmapFactory.decodeByteArray(data, 0, data.length, options, false); if (jc.isCancelled()) return null; if (options.outWidth < targetSize || options.outHeight < targetSize) { return null; @@ -184,8 +184,16 @@ public class DecodeUtils { options.inJustDecodeBounds = false; setOptionsMutable(options); - return ensureGLCompatibleBitmap( - BitmapFactory.decodeByteArray(data, 0, data.length, options)); + Bitmap bitmap = null; + + try { + bitmap = BitmapFactory.decodeByteArray(data, 0, data.length, options, false); + + } catch (OutOfMemoryError ex) { + bitmap = null; + Log.e(TAG, "OutOfMemoryError : image is too large"); + } + return ensureGLCompatibleBitmap(bitmap); } // TODO: This function should not be called directly from diff --git a/src/com/android/gallery3d/data/ImageCacheRequest.java b/src/com/android/gallery3d/data/ImageCacheRequest.java index 6cbc5c5ea..f93f6e28a 100644 --- a/src/com/android/gallery3d/data/ImageCacheRequest.java +++ b/src/com/android/gallery3d/data/ImageCacheRequest.java @@ -16,6 +16,9 @@ package com.android.gallery3d.data; +import android.drm.DrmManagerClient; +import android.drm.DrmStore.Action; +import android.drm.DrmStore.RightsStatus; import android.graphics.Bitmap; import android.graphics.BitmapFactory; @@ -32,14 +35,18 @@ abstract class ImageCacheRequest implements Job { private Path mPath; private int mType; private int mTargetSize; + private String mFilePath; + private String mMimeType; private long mTimeModified; public ImageCacheRequest(GalleryApp application, - Path path, long timeModified, int type, int targetSize) { + Path path, long timeModified, int type, int targetSize, String filePath, String mimetype) { mApplication = application; mPath = path; mType = type; mTargetSize = targetSize; + mFilePath = filePath; + mMimeType = mimetype; mTimeModified = timeModified; } @@ -53,6 +60,31 @@ abstract class ImageCacheRequest implements Job { public Bitmap run(JobContext jc) { ImageCacheService cacheService = mApplication.getImageCacheService(); + if (mFilePath != null && mFilePath.endsWith(".dcf")) { + DrmManagerClient drmClient = new DrmManagerClient(mApplication.getAndroidContext()); + mFilePath = mFilePath.replace("/storage/emulated/0", "/storage/emulated/legacy"); + + // This hack is added to work FL. It will remove after the sdcard permission issue solved + int statusDisplay = drmClient.checkRightsStatus(mFilePath, Action.DISPLAY); + statusDisplay = RightsStatus.RIGHTS_VALID; + int statusPlay = drmClient.checkRightsStatus(mFilePath, Action.PLAY); + statusPlay = RightsStatus.RIGHTS_VALID; + + if (mMimeType == null) { + if ((RightsStatus.RIGHTS_VALID != statusDisplay) + && (RightsStatus.RIGHTS_VALID != statusPlay)) { + return null; + } + } else if (mMimeType.startsWith("video/") + && RightsStatus.RIGHTS_VALID != statusPlay) { + return null; + } else if (mMimeType.startsWith("image/") + && RightsStatus.RIGHTS_VALID != statusDisplay) { + return null; + } + if (drmClient != null) drmClient.release(); + } + BytesBuffer buffer = MediaItem.getBytesBufferPool().get(); try { boolean found = cacheService.getImageData(mPath, mTimeModified, mType, buffer); diff --git a/src/com/android/gallery3d/data/LocalImage.java b/src/com/android/gallery3d/data/LocalImage.java index 2b01c1e22..32c4880d7 100644 --- a/src/com/android/gallery3d/data/LocalImage.java +++ b/src/com/android/gallery3d/data/LocalImage.java @@ -20,6 +20,8 @@ import android.annotation.TargetApi; import android.content.ContentResolver; import android.content.ContentValues; import android.database.Cursor; +import android.drm.DrmManagerClient; +import android.drm.DrmStore.DrmDeliveryType; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.BitmapRegionDecoder; @@ -173,16 +175,16 @@ public class LocalImage extends LocalMediaItem { @Override public Job requestImage(int type) { return new LocalImageRequest(mApplication, mPath, dateModifiedInSec, - type, filePath); + type, filePath, mimeType); } public static class LocalImageRequest extends ImageCacheRequest { private String mLocalFilePath; LocalImageRequest(GalleryApp application, Path path, long timeModified, - int type, String localFilePath) { + int type, String localFilePath, String mimetype) { super(application, path, timeModified, type, - MediaItem.getTargetSize(type)); + MediaItem.getTargetSize(type), localFilePath, mimetype); mLocalFilePath = localFilePath; } @@ -236,10 +238,24 @@ public class LocalImage extends LocalMediaItem { @Override public int getSupportedOperations() { - int operation = SUPPORT_DELETE | SUPPORT_SHARE | SUPPORT_CROP - | SUPPORT_SETAS | SUPPORT_PRINT | SUPPORT_INFO; + int operation = SUPPORT_DELETE | SUPPORT_SETAS | SUPPORT_INFO; + if (filePath != null && (filePath.endsWith(".dcf") || filePath.endsWith(".dm"))) { + filePath = filePath.replace("/storage/emulated/0", "/storage/emulated/legacy"); + operation |= SUPPORT_DRM_INFO; + DrmManagerClient drmClient = new DrmManagerClient(mApplication.getAndroidContext()); + ContentValues values = drmClient.getMetadata(filePath); + int drmType = values.getAsInteger("DRM-TYPE"); + Log.d(TAG, "getSupportedOperations:drmType returned= " + + Integer.toString(drmType) + " for path= " + filePath); + if (drmType == DrmDeliveryType.SEPARATE_DELIVERY) { + operation |= SUPPORT_SHARE; + } + if (drmClient != null) drmClient.release(); + } else { + operation |= SUPPORT_SHARE | SUPPORT_EDIT | SUPPORT_CROP | SUPPORT_PRINT; + } if (BitmapUtils.isSupportedByRegionDecoder(mimeType)) { - operation |= SUPPORT_FULL_IMAGE | SUPPORT_EDIT; + operation |= SUPPORT_FULL_IMAGE; } if (BitmapUtils.isRotationSupported(mimeType)) { @@ -347,4 +363,14 @@ public class LocalImage extends LocalMediaItem { public String getFilePath() { return filePath; } + + @Override + public void setConsumeRights(boolean flag) { + consumeRights = flag; + } + + @Override + public boolean getConsumeRights() { + return consumeRights; + } } diff --git a/src/com/android/gallery3d/data/LocalVideo.java b/src/com/android/gallery3d/data/LocalVideo.java index 4b8774ca4..d5e21e983 100644 --- a/src/com/android/gallery3d/data/LocalVideo.java +++ b/src/com/android/gallery3d/data/LocalVideo.java @@ -17,7 +17,10 @@ package com.android.gallery3d.data; import android.content.ContentResolver; +import android.content.ContentValues; import android.database.Cursor; +import android.drm.DrmManagerClient; +import android.drm.DrmStore.DrmDeliveryType; import android.graphics.Bitmap; import android.graphics.BitmapRegionDecoder; import android.net.Uri; @@ -152,17 +155,18 @@ public class LocalVideo extends LocalMediaItem { @Override public Job requestImage(int type) { - return new LocalVideoRequest(mApplication, getPath(), dateModifiedInSec, - type, filePath); + // Drm start + return new LocalVideoRequest(mApplication, getPath(), dateModifiedInSec,type, filePath, mimeType); + // Drm end } public static class LocalVideoRequest extends ImageCacheRequest { private String mLocalFilePath; LocalVideoRequest(GalleryApp application, Path path, long timeModified, - int type, String localFilePath) { + int type, String localFilePath, String mimetype) { super(application, path, timeModified, type, - MediaItem.getTargetSize(type)); + MediaItem.getTargetSize(type),localFilePath, mimetype); mLocalFilePath = localFilePath; } @@ -182,7 +186,24 @@ public class LocalVideo extends LocalMediaItem { @Override public int getSupportedOperations() { - return SUPPORT_DELETE | SUPPORT_SHARE | SUPPORT_PLAY | SUPPORT_INFO | SUPPORT_TRIM | SUPPORT_MUTE; + int supported = SUPPORT_DELETE | SUPPORT_PLAY | SUPPORT_INFO; + if (filePath != null && (filePath.endsWith(".dcf") || filePath.endsWith(".dm"))) { + supported |= SUPPORT_DRM_INFO; + DrmManagerClient drmClient = new DrmManagerClient(mApplication.getAndroidContext()); + ContentValues values = drmClient.getMetadata(filePath); + int drmType = values.getAsInteger("DRM-TYPE"); + Log.d("LocalVideo", "getSupportedOperations:drmType returned= " + + Integer.toString(drmType) + " for path= " + filePath); + if (drmType == DrmDeliveryType.SEPARATE_DELIVERY) { + supported |= SUPPORT_SHARE; + } + if (drmClient != null) drmClient.release(); + } else { + Log.e("LocalVideo", "yy:share added for path= " + filePath); + supported |= SUPPORT_SHARE; + } + + return supported; } @Override diff --git a/src/com/android/gallery3d/data/MediaObject.java b/src/com/android/gallery3d/data/MediaObject.java index 530ee306e..68a58ea70 100644 --- a/src/com/android/gallery3d/data/MediaObject.java +++ b/src/com/android/gallery3d/data/MediaObject.java @@ -42,12 +42,15 @@ public abstract class MediaObject { public static final int SUPPORT_CAMERA_SHORTCUT = 1 << 15; public static final int SUPPORT_MUTE = 1 << 16; public static final int SUPPORT_PRINT = 1 << 17; + public static final int SUPPORT_DRM_INFO = 1 << 18; public static final int SUPPORT_ALL = 0xffffffff; // These are the bits returned from getMediaType(): public static final int MEDIA_TYPE_UNKNOWN = 1; public static final int MEDIA_TYPE_IMAGE = 2; public static final int MEDIA_TYPE_VIDEO = 4; + public static final int MEDIA_TYPE_DRM_VIDEO = 5; + public static final int MEDIA_TYPE_DRM_IMAGE = 6; public static final int MEDIA_TYPE_ALL = MEDIA_TYPE_IMAGE | MEDIA_TYPE_VIDEO; public static final String MEDIA_TYPE_IMAGE_STRING = "image"; @@ -66,7 +69,7 @@ public abstract class MediaObject { public static final int CACHE_STATUS_CACHED_FULL = 3; private static long sVersionSerial = 0; - + protected boolean consumeRights = false; protected long mDataVersion; protected final Path mPath; @@ -145,6 +148,14 @@ public abstract class MediaObject { throw new UnsupportedOperationException(); } + public void setConsumeRights(boolean flag) { + throw new UnsupportedOperationException(); + } + + public boolean getConsumeRights() { + throw new UnsupportedOperationException(); + } + public static synchronized long nextVersionNumber() { return ++MediaObject.sVersionSerial; } diff --git a/src/com/android/gallery3d/data/UriImage.java b/src/com/android/gallery3d/data/UriImage.java index b3fe1de03..fba34a0b3 100644 --- a/src/com/android/gallery3d/data/UriImage.java +++ b/src/com/android/gallery3d/data/UriImage.java @@ -17,12 +17,17 @@ package com.android.gallery3d.data; import android.content.ContentResolver; +import android.content.ContentValues; +import android.database.Cursor; +import android.drm.DrmManagerClient; +import android.drm.DrmStore.DrmDeliveryType; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.BitmapFactory.Options; import android.graphics.BitmapRegionDecoder; import android.net.Uri; import android.os.ParcelFileDescriptor; +import android.provider.MediaStore.Video.VideoColumns; import com.android.gallery3d.app.GalleryApp; import com.android.gallery3d.app.PanoramaMetadataSupport; @@ -211,10 +216,45 @@ public class UriImage extends MediaItem { @Override public int getSupportedOperations() { - int supported = SUPPORT_PRINT | SUPPORT_SETAS; - if (isSharable()) supported |= SUPPORT_SHARE; + int supported = SUPPORT_SETAS; + String filePath = null; + String scheme = mUri.getScheme(); + if ("file".equals(scheme)) { + filePath = mUri.getPath(); + } else { + Cursor cursor = null; + try { + cursor = mApplication.getContentResolver().query(mUri, + new String[] {VideoColumns.DATA}, null, null, null); + if (cursor != null && cursor.moveToNext()) { + filePath = cursor.getString(0); + } + } catch (Throwable t) { + Log.w(TAG, "cannot get path from: " + mUri); + } finally { + if (cursor != null) cursor.close(); + } + } + + if (filePath != null && (filePath.endsWith(".dcf") || filePath.endsWith(".dm"))) { + supported |= SUPPORT_DRM_INFO; + filePath = filePath.replace("/storage/emulated/0", "/storage/emulated/legacy"); + DrmManagerClient drmClient = new DrmManagerClient(mApplication.getAndroidContext()); + ContentValues values = drmClient.getMetadata(filePath); + int drmType = values.getAsInteger("DRM-TYPE"); + Log.d(TAG, "getSupportedOperations:drmType returned= " + + Integer.toString(drmType) + " for path= " + filePath); + if (drmType == DrmDeliveryType.SEPARATE_DELIVERY) { + if (isSharable()) supported |= SUPPORT_SHARE; + } + if (drmClient != null) drmClient.release(); + } else { + supported |= SUPPORT_EDIT | SUPPORT_PRINT; + if (isSharable()) supported |= SUPPORT_SHARE; + } + if (BitmapUtils.isSupportedByRegionDecoder(mContentType)) { - supported |= SUPPORT_EDIT | SUPPORT_FULL_IMAGE; + supported |= SUPPORT_FULL_IMAGE; } return supported; } @@ -295,4 +335,14 @@ public class UriImage extends MediaItem { public int getRotation() { return mRotation; } + + @Override + public void setConsumeRights(boolean flag) { + consumeRights = flag; + } + + @Override + public boolean getConsumeRights() { + return consumeRights; + } } diff --git a/src/com/android/gallery3d/filtershow/crop/CropActivity.java b/src/com/android/gallery3d/filtershow/crop/CropActivity.java index 94c859333..21b283eed 100644 --- a/src/com/android/gallery3d/filtershow/crop/CropActivity.java +++ b/src/com/android/gallery3d/filtershow/crop/CropActivity.java @@ -115,6 +115,12 @@ public class CropActivity extends Activity { @Override public void onClick(View view) { startFinishOutput(); + if (mCropExtras != null && mCropExtras.getSetAsWallpaper()) { + Intent intent = new Intent("android.drmservice.intent.action.SET_WALLPAPER"); + intent.putExtra("DRM_TYPE", "OMAV1"); + intent.putExtra("DRM_FILE_PATH", mSourceUri.toString()); + CropActivity.this.sendBroadcast(intent); + } } }); } diff --git a/src/com/android/gallery3d/gadget/PhotoAppWidgetProvider.java b/src/com/android/gallery3d/gadget/PhotoAppWidgetProvider.java index 58466bf01..1dfbe3ff8 100644 --- a/src/com/android/gallery3d/gadget/PhotoAppWidgetProvider.java +++ b/src/com/android/gallery3d/gadget/PhotoAppWidgetProvider.java @@ -106,7 +106,7 @@ public class PhotoAppWidgetProvider extends AppWidgetProvider { context.getPackageName(), R.layout.photo_frame); try { byte[] data = entry.imageData; - Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length); + Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length, false); views.setImageViewBitmap(R.id.photo, bitmap); } catch (Throwable t) { Log.w(TAG, "cannot load widget image: " + appWidgetId, t); diff --git a/src/com/android/gallery3d/gadget/WidgetClickHandler.java b/src/com/android/gallery3d/gadget/WidgetClickHandler.java index e5b0a376c..642f3d650 100644 --- a/src/com/android/gallery3d/gadget/WidgetClickHandler.java +++ b/src/com/android/gallery3d/gadget/WidgetClickHandler.java @@ -57,6 +57,8 @@ public class WidgetClickHandler extends Activity { Intent intent; if (isValidDataUri(uri)) { intent = new Intent(Intent.ACTION_VIEW, uri); + intent.putExtra("WidgetClick", true); + // Used for checking whether it is from widget intent.putExtra(PhotoPage.KEY_IS_FROM_WIDGET, true); if (tediousBack) { diff --git a/src/com/android/gallery3d/glrenderer/NinePatchTexture.java b/src/com/android/gallery3d/glrenderer/NinePatchTexture.java index d0ddc46c3..2353f8b9b 100644 --- a/src/com/android/gallery3d/glrenderer/NinePatchTexture.java +++ b/src/com/android/gallery3d/glrenderer/NinePatchTexture.java @@ -50,7 +50,7 @@ public class NinePatchTexture extends ResourceTexture { BitmapFactory.Options options = new BitmapFactory.Options(); options.inPreferredConfig = Bitmap.Config.ARGB_8888; Bitmap bitmap = BitmapFactory.decodeResource( - mContext.getResources(), mResId, options); + mContext.getResources(), mResId, options, false); mBitmap = bitmap; setSize(bitmap.getWidth(), bitmap.getHeight()); byte[] chunkData = bitmap.getNinePatchChunk(); diff --git a/src/com/android/gallery3d/glrenderer/ResourceTexture.java b/src/com/android/gallery3d/glrenderer/ResourceTexture.java index eb8e8a517..d60a16c5a 100644 --- a/src/com/android/gallery3d/glrenderer/ResourceTexture.java +++ b/src/com/android/gallery3d/glrenderer/ResourceTexture.java @@ -19,6 +19,7 @@ package com.android.gallery3d.glrenderer; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; +import android.util.Log; import junit.framework.Assert; @@ -26,6 +27,7 @@ import junit.framework.Assert; // By default ResourceTexture is not opaque. public class ResourceTexture extends UploadedTexture { + private static final String TAG = "ResourceTexture"; protected final Context mContext; protected final int mResId; @@ -40,8 +42,15 @@ public class ResourceTexture extends UploadedTexture { protected Bitmap onGetBitmap() { BitmapFactory.Options options = new BitmapFactory.Options(); options.inPreferredConfig = Bitmap.Config.ARGB_8888; - return BitmapFactory.decodeResource( - mContext.getResources(), mResId, options); + Bitmap bitmap = null; + try { + bitmap = BitmapFactory.decodeResource(mContext.getResources(), mResId, options, false); + } catch (OutOfMemoryError ex) { + Log.e(TAG, "BitmapFactory decode resource out of memory"); + ex.printStackTrace(); + return null; + } + return bitmap; } @Override diff --git a/src/com/android/gallery3d/ui/AbstractSlotRenderer.java b/src/com/android/gallery3d/ui/AbstractSlotRenderer.java index 729439dc3..63bcbea5d 100644 --- a/src/com/android/gallery3d/ui/AbstractSlotRenderer.java +++ b/src/com/android/gallery3d/ui/AbstractSlotRenderer.java @@ -20,6 +20,7 @@ import android.content.Context; import android.graphics.Rect; import com.android.gallery3d.R; +import com.android.gallery3d.data.MediaObject; import com.android.gallery3d.glrenderer.FadeOutTexture; import com.android.gallery3d.glrenderer.GLCanvas; import com.android.gallery3d.glrenderer.NinePatchTexture; @@ -33,6 +34,7 @@ public abstract class AbstractSlotRenderer implements SlotView.SlotRenderer { private final ResourceTexture mPanoramaIcon; private final NinePatchTexture mFramePressed; private final NinePatchTexture mFrameSelected; + private final ResourceTexture mDrmIcon; private FadeOutTexture mFramePressedUp; protected AbstractSlotRenderer(Context context) { @@ -41,6 +43,7 @@ public abstract class AbstractSlotRenderer implements SlotView.SlotRenderer { mPanoramaIcon = new ResourceTexture(context, R.drawable.ic_360pano_holo_light); mFramePressed = new NinePatchTexture(context, R.drawable.grid_pressed); mFrameSelected = new NinePatchTexture(context, R.drawable.grid_selected); + mDrmIcon = new ResourceTexture(context, R.drawable.drm_image); } protected void drawContent(GLCanvas canvas, @@ -79,6 +82,19 @@ public abstract class AbstractSlotRenderer implements SlotView.SlotRenderer { mVideoPlayIcon.draw(canvas, (width - s) / 2, (height - s) / 2, s, s); } + protected void drawDrmOverlay(GLCanvas canvas, int width, int height, int Drm_mediaType) { + // Scale the video overlay to the height of the thumbnail and put it on the left side. + if (Drm_mediaType == MediaObject.MEDIA_TYPE_DRM_VIDEO) { + ResourceTexture v = mVideoOverlay; + float scale = (float) height / v.getHeight(); + int w = Math.round(scale * v.getWidth()); + int h = Math.round(scale * v.getHeight()); + v.draw(canvas, 0, 0, w, h); + } + int side = Math.min(width, height) / 6; + mDrmIcon.draw(canvas, (width - side) / 2, (height - side) / 2, side, side); + } + protected void drawPanoramaIcon(GLCanvas canvas, int width, int height) { int iconSize = Math.min(width, height) / 6; mPanoramaIcon.draw(canvas, (width - iconSize) / 2, (height - iconSize) / 2, diff --git a/src/com/android/gallery3d/ui/AlbumSetSlidingWindow.java b/src/com/android/gallery3d/ui/AlbumSetSlidingWindow.java index 8149df4b3..641115138 100644 --- a/src/com/android/gallery3d/ui/AlbumSetSlidingWindow.java +++ b/src/com/android/gallery3d/ui/AlbumSetSlidingWindow.java @@ -24,6 +24,7 @@ import com.android.gallery3d.app.AbstractGalleryActivity; import com.android.gallery3d.app.AlbumSetDataLoader; import com.android.gallery3d.common.Utils; import com.android.gallery3d.data.DataSourceType; +import com.android.gallery3d.data.LocalMediaItem; import com.android.gallery3d.data.MediaItem; import com.android.gallery3d.data.MediaObject; import com.android.gallery3d.data.MediaSet; @@ -80,6 +81,7 @@ public class AlbumSetSlidingWindow implements AlbumSetDataLoader.DataListener { public Path setPath; public String title; public int totalCount; + public int mediaType; public int sourceType; public int cacheFlag; public int cacheStatus; @@ -275,6 +277,18 @@ public class AlbumSetSlidingWindow implements AlbumSetDataLoader.DataListener { if (getDataVersion(cover) != entry.coverDataVersion) { entry.coverDataVersion = getDataVersion(cover); entry.rotation = (cover == null) ? 0 : cover.getRotation(); + + if (cover instanceof LocalMediaItem) { + String filePath = ((LocalMediaItem) cover).filePath; + if (filePath != null && (filePath.endsWith(".dcf") || filePath.endsWith(".dm"))) { + if (entry.mediaType == MediaObject.MEDIA_TYPE_IMAGE) { + entry.mediaType = MediaObject.MEDIA_TYPE_DRM_IMAGE; + } else if (entry.mediaType == MediaObject.MEDIA_TYPE_VIDEO) { + entry.mediaType = MediaObject.MEDIA_TYPE_DRM_VIDEO; + } + } + } + if (entry.coverLoader != null) { entry.coverLoader.recycle(); entry.coverLoader = null; diff --git a/src/com/android/gallery3d/ui/AlbumSetSlotRenderer.java b/src/com/android/gallery3d/ui/AlbumSetSlotRenderer.java index 5332ef89a..37f9b4339 100644 --- a/src/com/android/gallery3d/ui/AlbumSetSlotRenderer.java +++ b/src/com/android/gallery3d/ui/AlbumSetSlotRenderer.java @@ -183,7 +183,10 @@ public class AlbumSetSlotRenderer extends AbstractSlotRenderer { ((FadeInTexture) content).isAnimating()) { renderRequestFlags |= SlotView.RENDER_MORE_FRAME; } - + if ((entry.mediaType == MediaObject.MEDIA_TYPE_DRM_VIDEO) + || (entry.mediaType == MediaObject.MEDIA_TYPE_DRM_IMAGE)) { + drawDrmOverlay(canvas, width, height, entry.mediaType); + } return renderRequestFlags; } diff --git a/src/com/android/gallery3d/ui/AlbumSlidingWindow.java b/src/com/android/gallery3d/ui/AlbumSlidingWindow.java index fec7d1e92..a534c6add 100644 --- a/src/com/android/gallery3d/ui/AlbumSlidingWindow.java +++ b/src/com/android/gallery3d/ui/AlbumSlidingWindow.java @@ -24,6 +24,7 @@ import com.android.gallery3d.app.AlbumDataLoader; import com.android.gallery3d.common.Utils; import com.android.gallery3d.data.MediaItem; import com.android.gallery3d.data.MediaObject; +import com.android.gallery3d.data.LocalMediaItem; import com.android.gallery3d.data.MediaObject.PanoramaSupportCallback; import com.android.gallery3d.data.Path; import com.android.gallery3d.glrenderer.Texture; @@ -267,6 +268,18 @@ public class AlbumSlidingWindow implements AlbumDataLoader.DataListener { entry.mediaType = (item == null) ? MediaItem.MEDIA_TYPE_UNKNOWN : entry.item.getMediaType(); + + if (item instanceof LocalMediaItem) { + String filePath = ((LocalMediaItem)item).filePath; + if (filePath != null && (filePath.endsWith(".dcf") || filePath.endsWith(".dm"))) { + if (entry.mediaType == MediaObject.MEDIA_TYPE_IMAGE) { + entry.mediaType = MediaObject.MEDIA_TYPE_DRM_IMAGE; + } else if (entry.mediaType == MediaObject.MEDIA_TYPE_VIDEO) { + entry.mediaType = MediaObject.MEDIA_TYPE_DRM_VIDEO; + } + } + } + entry.path = (item == null) ? null : item.getPath(); entry.rotation = (item == null) ? 0 : item.getRotation(); entry.contentLoader = new ThumbnailLoader(slotIndex, entry.item); diff --git a/src/com/android/gallery3d/ui/AlbumSlotRenderer.java b/src/com/android/gallery3d/ui/AlbumSlotRenderer.java index dc6c89b0e..7f97693e3 100644 --- a/src/com/android/gallery3d/ui/AlbumSlotRenderer.java +++ b/src/com/android/gallery3d/ui/AlbumSlotRenderer.java @@ -125,6 +125,9 @@ public class AlbumSlotRenderer extends AbstractSlotRenderer { if (entry.mediaType == MediaObject.MEDIA_TYPE_VIDEO) { drawVideoOverlay(canvas, width, height); + } else if ((entry.mediaType == MediaObject.MEDIA_TYPE_DRM_VIDEO) + || (entry.mediaType == MediaObject.MEDIA_TYPE_DRM_IMAGE)) { + drawDrmOverlay(canvas, width, height, entry.mediaType); } if (entry.isPanorama) { diff --git a/src/com/android/gallery3d/ui/MenuExecutor.java b/src/com/android/gallery3d/ui/MenuExecutor.java index 1ace71829..00a1459b0 100644 --- a/src/com/android/gallery3d/ui/MenuExecutor.java +++ b/src/com/android/gallery3d/ui/MenuExecutor.java @@ -24,8 +24,11 @@ import android.content.DialogInterface; import android.content.DialogInterface.OnCancelListener; import android.content.DialogInterface.OnClickListener; import android.content.Intent; +import android.database.Cursor; +import android.net.Uri; import android.os.Handler; import android.os.Message; +import android.provider.MediaStore.Video.VideoColumns; import android.support.v4.print.PrintHelper; import android.view.Menu; import android.view.MenuItem; @@ -179,7 +182,7 @@ public class MenuExecutor { boolean supportInfo = (supported & MediaObject.SUPPORT_INFO) != 0; boolean supportPrint = (supported & MediaObject.SUPPORT_PRINT) != 0; supportPrint &= PrintHelper.systemSupportsPrint(); - + boolean supportDrmInfo = (supported & MediaObject.SUPPORT_DRM_INFO) != 0; setMenuItemVisible(menu, R.id.action_delete, supportDelete); setMenuItemVisible(menu, R.id.action_rotate_ccw, supportRotate); setMenuItemVisible(menu, R.id.action_rotate_cw, supportRotate); @@ -195,6 +198,7 @@ public class MenuExecutor { // setMenuItemVisible(menu, R.id.action_simple_edit, supportEdit); setMenuItemVisible(menu, R.id.action_details, supportInfo); setMenuItemVisible(menu, R.id.print, supportPrint); + setMenuItemVisible(menu, R.id.action_drm_info, supportDrmInfo); } public static void updateMenuForPanorama(Menu menu, boolean shareAsPanorama360, @@ -271,6 +275,36 @@ public class MenuExecutor { case R.id.action_show_on_map: title = R.string.show_on_map; break; + case R.id.action_drm_info: + DataManager manager = mActivity.getDataManager(); + Path path = getSingleSelectedPath(); + Uri uri = manager.getContentUri(path); + Log.d(TAG, "onMenuClicked:" + uri); + String filepath = null; + String scheme = uri.getScheme(); + if ("file".equals(scheme)) { + filepath = uri.getPath(); + } else { + Cursor cursor = null; + try { + cursor = mActivity.getAndroidContext().getContentResolver().query(uri, + new String[] {VideoColumns.DATA}, null, null, null); + if (cursor != null && cursor.moveToNext()) { + filepath = cursor.getString(0); + } + } catch (Throwable t) { + Log.w(TAG, "cannot get path from: " + uri); + } finally { + if (cursor != null) cursor.close(); + } + } + Intent drmintent = new Intent("android.drmservice.intent.action.SHOW_PROPERTIES"); + filepath = filepath.replace("/storage/emulated/0", "/storage/emulated/legacy"); + drmintent.putExtra("DRM_FILE_PATH", filepath); + drmintent.putExtra("DRM_TYPE", "OMAV1"); + mActivity.getAndroidContext().sendBroadcast(drmintent); + title = R.string.drm_license_info; + break; default: return; } -- cgit v1.2.3