From 1935f4c5db2ec505a7780958b2f76366fde851c5 Mon Sep 17 00:00:00 2001 From: kaiyiz Date: Wed, 16 Jul 2014 10:39:21 +0800 Subject: Gallery2: Fix monkey test fail When click undo in filtershowActivity,the position can't be -1 In FilterShowActivity,the preset and Rect shouldn't be null. Add some check for position and null pointer check for preset and rect CRs-fixed: 693810 Change-Id: I70fa2ff86d40ad483474b60ab9071ccb151bd445 --- src/com/android/gallery3d/filtershow/imageshow/MasterImage.java | 3 +++ src/com/android/gallery3d/filtershow/pipeline/ImagePreset.java | 8 +++++--- src/com/android/gallery3d/filtershow/ui/ExportDialog.java | 7 +++++++ 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/com/android/gallery3d/filtershow/imageshow/MasterImage.java b/src/com/android/gallery3d/filtershow/imageshow/MasterImage.java index f6b97f11f..4b43d7672 100644 --- a/src/com/android/gallery3d/filtershow/imageshow/MasterImage.java +++ b/src/com/android/gallery3d/filtershow/imageshow/MasterImage.java @@ -271,6 +271,9 @@ public class MasterImage implements RenderingRequestCaller { public void onHistoryItemClick(int position) { HistoryItem historyItem = mHistory.getItem(position); // We need a copy from the history + if (historyItem == null) { + return; + } ImagePreset newPreset = new ImagePreset(historyItem.getImagePreset()); // don't need to add it to the history setPreset(newPreset, historyItem.getFilterRepresentation(), false); diff --git a/src/com/android/gallery3d/filtershow/pipeline/ImagePreset.java b/src/com/android/gallery3d/filtershow/pipeline/ImagePreset.java index 4765a5990..e2945e9b9 100644 --- a/src/com/android/gallery3d/filtershow/pipeline/ImagePreset.java +++ b/src/com/android/gallery3d/filtershow/pipeline/ImagePreset.java @@ -67,9 +67,11 @@ public class ImagePreset { } public ImagePreset(ImagePreset source) { - for (int i = 0; i < source.mFilters.size(); i++) { - FilterRepresentation sourceRepresentation = source.mFilters.elementAt(i); - mFilters.add(sourceRepresentation.copy()); + if (source != null && source.mFilters != null) { + for (int i = 0; i < source.mFilters.size(); i++) { + FilterRepresentation sourceRepresentation = source.mFilters.elementAt(i); + mFilters.add(sourceRepresentation.copy()); + } } } diff --git a/src/com/android/gallery3d/filtershow/ui/ExportDialog.java b/src/com/android/gallery3d/filtershow/ui/ExportDialog.java index b42c9f367..7fdd36d0f 100644 --- a/src/com/android/gallery3d/filtershow/ui/ExportDialog.java +++ b/src/com/android/gallery3d/filtershow/ui/ExportDialog.java @@ -109,6 +109,13 @@ public class ExportDialog extends DialogFragment implements View.OnClickListener ImagePreset preset = MasterImage.getImage().getPreset(); mOriginalBounds = preset.finalGeometryRect(mOriginalBounds.width(), mOriginalBounds.height()); + if (preset != null) { + mOriginalBounds = preset.finalGeometryRect(mOriginalBounds.width(), + mOriginalBounds.height()); + } + if (mOriginalBounds == null) { + return null; + } mRatio = mOriginalBounds.width() / (float) mOriginalBounds.height(); mWidthText.setText("" + mOriginalBounds.width()); mHeightText.setText("" + mOriginalBounds.height()); -- cgit v1.2.3 From 9b405b8e1c3c8ccd9b75ff5f3a23b18ceb8842ae Mon Sep 17 00:00:00 2001 From: kaiyiz Date: Wed, 10 Dec 2014 17:20:18 +0800 Subject: Gallery2: Play all video file can pre/next in FileExplorer The initial video can only previous and next in the current directory. List all video file and play it all through pre/next function CRs-Fixed: 704384 Change-Id: Ifd2caac0f2f2df61ee08af82ac7324848807055c --- .../codeaurora/gallery3d/ext/MovieListLoader.java | 28 ++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/org/codeaurora/gallery3d/ext/MovieListLoader.java b/src/org/codeaurora/gallery3d/ext/MovieListLoader.java index cb3505650..840477ff6 100644 --- a/src/org/codeaurora/gallery3d/ext/MovieListLoader.java +++ b/src/org/codeaurora/gallery3d/ext/MovieListLoader.java @@ -115,6 +115,9 @@ public class MovieListLoader implements IMovieListLoader { //from gallery, gallery3D, videoplayer long curId = Long.parseLong(uri.getPathSegments().get(3)); movieList = fillUriList(null, null, curId, params[0]); + } else if (uristr.toLowerCase().startsWith("file://")) { + long curId = getCursorId(uri); + movieList = fillUriList(null, null, curId, params[0]); } } } else { //get current list @@ -199,5 +202,30 @@ public class MovieListLoader implements IMovieListLoader { } return movieList; } + + private long getCursorId(Uri uri) { + long curId = -1; + Cursor cursor = null; + String data = Uri.decode(uri.toString()); + data = data.replaceAll("'", "''"); + String where = "_data LIKE '%" + data.replaceFirst("file:///", "") + "'"; + try { + cursor = mCr.query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, + new String[] { + "_id" + }, where, null, null); + + if (cursor != null && cursor.moveToFirst()) { + curId = cursor.getLong(0); + } + } catch (final SQLiteException e) { + e.printStackTrace(); + } finally { + if (cursor != null) { + cursor.close(); + } + } + return curId; + } } } -- cgit v1.2.3 From fc2a0a61de5bc6d7ba3a2ae3de96a9f2bb178390 Mon Sep 17 00:00:00 2001 From: kayiz Date: Tue, 4 Mar 2014 15:05:22 +0800 Subject: Gallery2: Fix cropped picture cannot be saved. When click the saveButton to save the cropped picture, We found the source picture uri and the cropped picture uri are the same,which cause the cropped picture can not be saved. Closed file Stream of mInStream before re-open it for the same file. CRs-Fixed: 622666 Change-Id: Ifcaa39ea76c141021259fad891411c59f7587903 --- .../gallery3d/filtershow/crop/CropActivity.java | 23 +++++++++++----------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/com/android/gallery3d/filtershow/crop/CropActivity.java b/src/com/android/gallery3d/filtershow/crop/CropActivity.java index 387803740..94c859333 100644 --- a/src/com/android/gallery3d/filtershow/crop/CropActivity.java +++ b/src/com/android/gallery3d/filtershow/crop/CropActivity.java @@ -400,16 +400,8 @@ public class CropActivity extends Activity { mOutputX = outputX; mOutputY = outputY; - if ((flags & DO_EXTRA_OUTPUT) != 0) { - if (mOutUri == null) { - Log.w(LOGTAG, "cannot write file, no output URI given"); - } else { - try { - mOutStream = getContentResolver().openOutputStream(mOutUri); - } catch (FileNotFoundException e) { - Log.w(LOGTAG, "cannot write file: " + mOutUri.toString(), e); - } - } + if ((flags & DO_EXTRA_OUTPUT) != 0 && mOutUri == null) { + Log.w(LOGTAG, "cannot write file, no output URI given"); } if ((flags & (DO_EXTRA_OUTPUT | DO_SET_WALLPAPER)) != 0) { @@ -542,7 +534,14 @@ public class CropActivity extends Activity { // Get output compression format CompressFormat cf = convertExtensionToCompressFormat(getFileExtension(mOutputFormat)); - + Utils.closeSilently(mInStream); + if (mOutUri != null) { + try { + mOutStream = getContentResolver().openOutputStream(mOutUri); + } catch (FileNotFoundException e) { + Log.w(LOGTAG, "cannot write file: " + mOutUri.toString(), e); + } + } // If we only need to output to a URI, compress straight to file if (mFlags == DO_EXTRA_OUTPUT) { if (mOutStream == null @@ -604,7 +603,7 @@ public class CropActivity extends Activity { @Override protected void onPostExecute(Boolean result) { Utils.closeSilently(mOutStream); - Utils.closeSilently(mInStream); + // Utils.closeSilently(mInStream); doneBitmapIO(result.booleanValue(), mResultIntent); } -- cgit v1.2.3 From 807e83e760488e00daa8f9eee0e3dee3e357c4a1 Mon Sep 17 00:00:00 2001 From: kaiyiz Date: Sat, 26 Apr 2014 10:27:13 +0800 Subject: Gallery2: Fix menu display inconsistent with its cluster MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The operation order is not correct.We should first execute the change of cluster,then display menu title according to the cluster.But we do the opposite operation,which cause the menu will always display last cluster‘s corresponding menu and cause this bug happened. Modify the operation order. CRs-fixed: 619812 Change-Id: I6cd3c82e065cef5a463e06295bf332e1459500e3 --- src/com/android/gallery3d/app/AlbumSetPage.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/com/android/gallery3d/app/AlbumSetPage.java b/src/com/android/gallery3d/app/AlbumSetPage.java index 1dca84068..068ac33a0 100644 --- a/src/com/android/gallery3d/app/AlbumSetPage.java +++ b/src/com/android/gallery3d/app/AlbumSetPage.java @@ -547,6 +547,13 @@ public class AlbumSetPage extends ActivityState implements inflater.inflate(R.menu.albumset, menu); boolean wasShowingClusterMenu = mShowClusterMenu; mShowClusterMenu = !inAlbum; + if (mShowClusterMenu != wasShowingClusterMenu) { + if (mShowClusterMenu) { + mActionBar.enableClusterMenu(mSelectedAction, this); + } else { + mActionBar.disableClusterMenu(true); + } + } boolean selectAlbums = !inAlbum && mActionBar.getClusterTypeAction() == FilterUtils.CLUSTER_BY_ALBUM; MenuItem selectItem = menu.findItem(R.id.action_select); @@ -571,13 +578,6 @@ public class AlbumSetPage extends ActivityState implements mActionBar.setTitle(mTitle); mActionBar.setSubtitle(mSubtitle); - if (mShowClusterMenu != wasShowingClusterMenu) { - if (mShowClusterMenu) { - mActionBar.enableClusterMenu(mSelectedAction, this); - } else { - mActionBar.disableClusterMenu(true); - } - } } return true; } -- cgit v1.2.3 From f613cf760c6cfed0867aa247d43b909b13d446c0 Mon Sep 17 00:00:00 2001 From: kaiyiz Date: Wed, 4 Jun 2014 17:36:42 +0800 Subject: Gallery2: Fix menu bar layout display error in portrait mode The forward button is interlock with separate line. Modify layout param to make the layout display normal. CRs-fixed: 674514 Change-Id: Idf09aee09c67ad943109ad054fe8d4bfa41e4061 --- src/com/android/gallery3d/app/MovieControllerOverlay.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/android/gallery3d/app/MovieControllerOverlay.java b/src/com/android/gallery3d/app/MovieControllerOverlay.java index 5f2ba06e5..93fc3cf79 100644 --- a/src/com/android/gallery3d/app/MovieControllerOverlay.java +++ b/src/com/android/gallery3d/app/MovieControllerOverlay.java @@ -799,7 +799,7 @@ public class MovieControllerOverlay extends CommonControllerOverlay implements mContollerButtons.setGravity(Gravity.CENTER); LinearLayout.LayoutParams buttonParam = new LinearLayout.LayoutParams( - mTimeBarHeight, mTimeBarHeight); + mButtonWidth, mTimeBarHeight); mRewind = new ImageView(context); mRewind.setImageResource(R.drawable.icn_media_rewind); mRewind.setScaleType(ScaleType.CENTER); -- cgit v1.2.3 From 1eb037d73381b64130f20894d834152add8959a8 Mon Sep 17 00:00:00 2001 From: mqi Date: Wed, 26 Nov 2014 17:25:06 +0800 Subject: Gallery2: Clear Bookmark when complete video play After video loaded, there will be a check for bookmark, but if the video is finish onCompletion, this bookmark will still not change Clear bookmark when onCompletion Change-Id: I0eca9b84746e08df68685c38b843281a58b10cb2 CRs-Fixed: 763193 --- src/com/android/gallery3d/app/MovieActivity.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/com/android/gallery3d/app/MovieActivity.java b/src/com/android/gallery3d/app/MovieActivity.java index ff874fbe0..8ee44402b 100644 --- a/src/com/android/gallery3d/app/MovieActivity.java +++ b/src/com/android/gallery3d/app/MovieActivity.java @@ -192,6 +192,9 @@ public class MovieActivity extends Activity { public void onCompletion() { if (mFinishOnCompletion) { finish(); + mControlResumed = false; + Bookmarker mBookmarker = new Bookmarker(MovieActivity.this); + mBookmarker.setBookmark(mMovieItem.getUri(), 0, 1); } } }; -- cgit v1.2.3 From 4608740c8f847c90fa4b734ffeb29d4bcef6008f Mon Sep 17 00:00:00 2001 From: kaiyiz Date: Mon, 18 Aug 2014 09:20:01 +0800 Subject: Gallery2: Gallery force close during Customer Monkey test. When browser is forbidden to start, the MENU_INPUT_URL menu will cause force close problem. When press MENU_INPUT_URL with browser is forbidden to start, it will show a toast to remain that can not load. CRs-Fixed: 710730 Change-Id: I8c8965dc87affc262ee1fda5e604dbb36f5642b7 --- src/org/codeaurora/gallery3d/video/StreamingHooker.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/org/codeaurora/gallery3d/video/StreamingHooker.java b/src/org/codeaurora/gallery3d/video/StreamingHooker.java index fdcc14c50..7def5d8a0 100755 --- a/src/org/codeaurora/gallery3d/video/StreamingHooker.java +++ b/src/org/codeaurora/gallery3d/video/StreamingHooker.java @@ -1,11 +1,13 @@ package org.codeaurora.gallery3d.video; +import android.content.ActivityNotFoundException; import android.content.Intent; import android.net.Uri; import android.provider.Browser; import android.util.Log; import android.view.Menu; import android.view.MenuItem; +import android.widget.Toast; import com.android.gallery3d.R; import org.codeaurora.gallery3d.ext.MovieUtils; @@ -61,7 +63,14 @@ public class StreamingHooker extends MovieHooker { intent.setData(Uri.parse(URI_STR)); intent.putExtra(EXTRA_NAME, true); intent.putExtra(Browser.EXTRA_APPLICATION_ID, APN_NAME); - getContext().startActivity(intent); + + try { + getContext().startActivity(intent); + } catch (ActivityNotFoundException e) { + Toast.makeText(getContext(), + R.string.fail_to_load, Toast.LENGTH_LONG).show(); + } + if (LOG) { Log.v(TAG, "gotoInputUrl() appName=" + APN_NAME); } -- cgit v1.2.3 From a61dd04626f156d65357f846bbc1d9be6ca224d7 Mon Sep 17 00:00:00 2001 From: kaiyiz Date: Wed, 11 Dec 2013 10:31:29 +0800 Subject: MoviePlayer: prevent resume dialog for live streaming The player should not offer "resume playing" dialog for live streaming when user navigates back to it. (cherry picked from commit 3a16d7f019fc77c54ce38a137507ba5e5ac1ae8b) Change-Id: I7fe6727ab884056a9135d1fa5ab21125570f70a3 CRs-Fixed: 637212 --- src/com/android/gallery3d/app/MoviePlayer.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/com/android/gallery3d/app/MoviePlayer.java b/src/com/android/gallery3d/app/MoviePlayer.java index 098fa79d8..e5874fd1c 100755 --- a/src/com/android/gallery3d/app/MoviePlayer.java +++ b/src/com/android/gallery3d/app/MoviePlayer.java @@ -300,9 +300,16 @@ public class MoviePlayer implements } else { mTState = TState.PLAYING; mFirstBePlayed = true; - final BookmarkerInfo bookmark = mBookmarker.getBookmark(mMovieItem.getUri()); - if (bookmark != null) { - showResumeDialog(movieActivity, bookmark); + String mUri = mMovieItem.getUri().toString(); + boolean isLive = mUri.startsWith("rtsp://") && (mUri.contains(".sdp") + || mUri.contains(".smil")); + if (!isLive) { + final BookmarkerInfo bookmark = mBookmarker.getBookmark(mMovieItem.getUri()); + if (bookmark != null) { + showResumeDialog(movieActivity, bookmark); + } else { + doStartVideo(false, 0, 0); + } } else { doStartVideo(false, 0, 0); } -- cgit v1.2.3 From 3be69402630daac812f32ee152fd0d536b74e39e Mon Sep 17 00:00:00 2001 From: xiaoqiny Date: Thu, 25 Dec 2014 13:39:42 +0800 Subject: Gallery2: Fix force close issue when trim video - Only mp4 and 3gp file support trim function Change-Id: I6e254ca6d5445d62b0276695667f4bdb07f9a59c CRs-Fixed: 652838 --- Android.mk | 2 +- proguard.flags | 4 ++++ res/values/strings.xml | 1 + src/com/android/gallery3d/app/PhotoPage.java | 12 ++++++++++-- 4 files changed, 16 insertions(+), 3 deletions(-) diff --git a/Android.mk b/Android.mk index 3d5663e6b..ef218f735 100644 --- a/Android.mk +++ b/Android.mk @@ -31,7 +31,7 @@ LOCAL_PACKAGE_NAME := Gallery2 LOCAL_OVERRIDES_PACKAGES := Gallery Gallery3D GalleryNew3D -LOCAL_SDK_VERSION := current +#LOCAL_SDK_VERSION := current LOCAL_JNI_SHARED_LIBRARIES := libjni_eglfence libjni_filtershow_filters librsjni libjni_jpegstream diff --git a/proguard.flags b/proguard.flags index 65104ec1e..fc5aef3b7 100644 --- a/proguard.flags +++ b/proguard.flags @@ -1,6 +1,10 @@ # Disable the warnings of using dynamic method call in common library. -dontnote com.android.gallery3d.common.* +#Avoid the library class dependency error +-dontwarn android.view.inputmethod.InputMethodManager +-dontwarn android.content.res.Resources + # Keep all classes extended from com.android.gallery3d.common.Entry # Since we annotate on the fields and use reflection to create SQL # according to those field. diff --git a/res/values/strings.xml b/res/values/strings.xml index e19f95082..fedb64f69 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -1121,4 +1121,5 @@ CHAR LIMIT = NONE] --> Sorry, this video file can not be trimmed + Only mp4 and 3gp file can be trimmed diff --git a/src/com/android/gallery3d/app/PhotoPage.java b/src/com/android/gallery3d/app/PhotoPage.java index 915fdab5a..2fed32f88 100644 --- a/src/com/android/gallery3d/app/PhotoPage.java +++ b/src/com/android/gallery3d/app/PhotoPage.java @@ -25,6 +25,7 @@ import android.content.Intent; import android.content.pm.PackageManager; import android.content.res.Configuration; import android.graphics.Rect; +import android.media.MediaFile; import android.net.Uri; import android.nfc.NfcAdapter; import android.nfc.NfcAdapter.CreateBeamUrisCallback; @@ -1057,8 +1058,15 @@ public abstract class PhotoPage extends ActivityState implements Intent intent = new Intent(mActivity, TrimVideo.class); intent.setData(manager.getContentUri(path)); // We need the file path to wrap this into a RandomAccessFile. - intent.putExtra(KEY_MEDIA_ITEM_PATH, current.getFilePath()); - mActivity.startActivityForResult(intent, REQUEST_TRIM); + String str = android.media.MediaFile.getMimeTypeForFile(current.getFilePath()); + if("video/mp4".equals(str) || "video/mpeg4".equals(str) + || "video/3gpp".equals(str) || "video/3gpp2".equals(str)) { + intent.putExtra(KEY_MEDIA_ITEM_PATH, current.getFilePath()); + mActivity.startActivityForResult(intent, REQUEST_TRIM); + } else { + Toast.makeText(mActivity,mActivity.getString(R.string.can_not_trim), + Toast.LENGTH_SHORT).show(); + } return true; } case R.id.action_mute: { -- cgit v1.2.3 From 7996c173550c744813663f79e4c7bfbc274d7bd7 Mon Sep 17 00:00:00 2001 From: kaiyiz Date: Mon, 8 Dec 2014 16:51:21 +0800 Subject: Gallery2: Fix crop after straighten bug During straighten and crop, there will be a crop Rect exits, the comparement of these two Rect is not perfect, so the two rect is considered to be different, and the Representation is wrong. Set the origenal Rect equals to representation. CRs-Fixed: 766877 Change-Id: Id76dfef360cdaff109cdce505cb5f289691645c6 --- .../android/gallery3d/filtershow/filters/FilterCropRepresentation.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/com/android/gallery3d/filtershow/filters/FilterCropRepresentation.java b/src/com/android/gallery3d/filtershow/filters/FilterCropRepresentation.java index ba697d87f..98afc3a08 100644 --- a/src/com/android/gallery3d/filtershow/filters/FilterCropRepresentation.java +++ b/src/com/android/gallery3d/filtershow/filters/FilterCropRepresentation.java @@ -65,6 +65,9 @@ public class FilterCropRepresentation extends FilterRepresentation { return false; } FilterCropRepresentation crop = (FilterCropRepresentation) rep; + if (crop.isNil()) { + return true; + } if (mCrop.bottom != crop.mCrop.bottom || mCrop.left != crop.mCrop.left || mCrop.right != crop.mCrop.right -- cgit v1.2.3 From 2fa1c956a30ac99b0f13f6b6f752c086e1898654 Mon Sep 17 00:00:00 2001 From: "Jing (Mia) Wang" Date: Thu, 18 Dec 2014 10:21:06 +0800 Subject: Gallery2: Add leave selection mode judgement The method of isCancelled in thread pool is a nonsynchronous method, as a result, there is a possibility that the job is not cancelled after leave selection mode, and the getSelectedMediaObjects is still running. Finish getSelectedMediaObjects when selection mode is quit. CRs-Fixed: 769028 Change-Id: Icb7c3f9d1f3e14536f32a6401337e844481ad646 --- src/com/android/gallery3d/ui/ActionModeHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/android/gallery3d/ui/ActionModeHandler.java b/src/com/android/gallery3d/ui/ActionModeHandler.java index 6b4f10312..411c578a5 100644 --- a/src/com/android/gallery3d/ui/ActionModeHandler.java +++ b/src/com/android/gallery3d/ui/ActionModeHandler.java @@ -272,7 +272,7 @@ public class ActionModeHandler implements Callback, PopupList.OnPopupItemClickLi ArrayList selected = new ArrayList(); DataManager manager = mActivity.getDataManager(); for (Path path : unexpandedPaths) { - if (jc.isCancelled()) { + if (jc.isCancelled() || !mSelectionManager.inSelectionMode()) { return null; } selected.add(manager.getMediaObject(path)); -- cgit v1.2.3 From 22282e36cbb36d77b747d44695f023bdfd715b91 Mon Sep 17 00:00:00 2001 From: Surajit Podder Date: Mon, 29 Dec 2014 14:09:06 +0530 Subject: Gallery2: Pause music playback while playing video Add changes to send pause command to music service from MoviePlayer. Change-Id: I3532ecee34f197fdca04f678cc18ae542794ae83 CRs-Fixed: 765206 --- src/com/android/gallery3d/app/MoviePlayer.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/com/android/gallery3d/app/MoviePlayer.java b/src/com/android/gallery3d/app/MoviePlayer.java index e5874fd1c..480bc90ab 100755 --- a/src/com/android/gallery3d/app/MoviePlayer.java +++ b/src/com/android/gallery3d/app/MoviePlayer.java @@ -89,6 +89,11 @@ public class MoviePlayer implements private static final int KEYCODE_MEDIA_PLAY = 126; private static final int KEYCODE_MEDIA_PAUSE = 127; + // Copied from MediaPlaybackService in the Music Player app. + private static final String SERVICECMD = "com.android.music.musicservicecommand"; + private static final String CMDNAME = "command"; + private static final String CMDPAUSE = "pause"; + private static final String KEY_VIDEO_CAN_SEEK = "video_can_seek"; private static final String KEY_VIDEO_CAN_PAUSE = "video_can_pause"; private static final String KEY_VIDEO_LAST_DURATION = "video_last_duration"; @@ -285,6 +290,10 @@ public class MoviePlayer implements mAudioBecomingNoisyReceiver = new AudioBecomingNoisyReceiver(); mAudioBecomingNoisyReceiver.register(); + Intent i = new Intent(SERVICECMD); + i.putExtra(CMDNAME, CMDPAUSE); + movieActivity.sendBroadcast(i); + // Listen for broadcasts related to user-presence final IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_SCREEN_OFF); -- cgit v1.2.3 From c4213e017d54db39f3b5285224cec98460c73de4 Mon Sep 17 00:00:00 2001 From: Li Sun Date: Thu, 16 Jan 2014 11:07:46 +0800 Subject: Gallery2: fix the video playback after system language changed - when system language changed, the activity would be destroyed and recreated. The subobject MoviePlayer would be also recreated. But in this case, MoviePlayer doesn't set some parameters like the URI, duration and etc. It cause the video playback failed. - add the related function calls to restart the video playback. Change-Id: I8dc011216bb5bcee8903ba3873ce37582927af45 CRs-Fixed: 597934 --- src/com/android/gallery3d/app/MoviePlayer.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/com/android/gallery3d/app/MoviePlayer.java b/src/com/android/gallery3d/app/MoviePlayer.java index e5874fd1c..3e882ef58 100755 --- a/src/com/android/gallery3d/app/MoviePlayer.java +++ b/src/com/android/gallery3d/app/MoviePlayer.java @@ -297,6 +297,9 @@ public class MoviePlayer implements mResumeableTime = savedInstance.getLong(KEY_RESUMEABLE_TIME, Long.MAX_VALUE); onRestoreInstanceState(savedInstance); mHasPaused = true; + doStartVideo(true, mVideoPosition, mVideoLastDuration,false); + mVideoView.start(); + mActivityContext.initEffects(mVideoView.getAudioSessionId()); } else { mTState = TState.PLAYING; mFirstBePlayed = true; -- cgit v1.2.3 From 187612064c2b35812e38adf25b5f106c72e9fcb2 Mon Sep 17 00:00:00 2001 From: kaiyiz Date: Thu, 18 Dec 2014 17:04:03 +0800 Subject: Gallery2: Add null pointer judgement for monkey The master image's parameters are null, as a result, there is a lot of NullPointerException during Monkey test. Add some judgement before using these parameters, return if null. CRs-Fixed: 770284 Change-Id: Ie8825f920ced2261908c19555173d36fdebca5a1 --- src/com/android/gallery3d/filtershow/state/StatePanel.java | 4 +++- src/com/android/gallery3d/filtershow/ui/ExportDialog.java | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/com/android/gallery3d/filtershow/state/StatePanel.java b/src/com/android/gallery3d/filtershow/state/StatePanel.java index 95c2df991..192400315 100644 --- a/src/com/android/gallery3d/filtershow/state/StatePanel.java +++ b/src/com/android/gallery3d/filtershow/state/StatePanel.java @@ -48,7 +48,9 @@ public class StatePanel extends Fragment { View panel = mMainView.findViewById(R.id.listStates); track = (StatePanelTrack) panel; - track.setAdapter(MasterImage.getImage().getState()); + StateAdapter imageStateAdapter = MasterImage.getImage().getState(); + if (imageStateAdapter == null) return null; + track.setAdapter(imageStateAdapter); mToggleVersionsPanel = (ImageButton) mMainView.findViewById(R.id.toggleVersionsPanel); if (FilterShowHelper.shouldUseVersions()) { if (mToggleVersionsPanel.getVisibility() == View.GONE diff --git a/src/com/android/gallery3d/filtershow/ui/ExportDialog.java b/src/com/android/gallery3d/filtershow/ui/ExportDialog.java index 7fdd36d0f..001e07589 100644 --- a/src/com/android/gallery3d/filtershow/ui/ExportDialog.java +++ b/src/com/android/gallery3d/filtershow/ui/ExportDialog.java @@ -107,6 +107,7 @@ public class ExportDialog extends DialogFragment implements View.OnClickListener mOriginalBounds = MasterImage.getImage().getOriginalBounds(); ImagePreset preset = MasterImage.getImage().getPreset(); + if (mOriginalBounds == null || preset == null) return null; mOriginalBounds = preset.finalGeometryRect(mOriginalBounds.width(), mOriginalBounds.height()); if (preset != null) { -- cgit v1.2.3 From 63581873a606fdaad3c9667c4d07908b9d7954c3 Mon Sep 17 00:00:00 2001 From: kaiyiz Date: Sun, 4 Jan 2015 10:18:20 +0800 Subject: Gallery2: Fix color chooser There is another problem for this issue: the border of color is not set well for the flag of mSelectedButton. Set mSelectedButton when set up. CRs-Fixed: 764078 Change-Id: Ibaddb66abe425bdc95a1f78a58522a3b4449ae80 --- .../android/gallery3d/filtershow/controller/ColorChooser.java | 9 ++++++++- .../gallery3d/filtershow/filters/FilterDrawRepresentation.java | 5 +++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/com/android/gallery3d/filtershow/controller/ColorChooser.java b/src/com/android/gallery3d/filtershow/controller/ColorChooser.java index f9f29bccc..82ce80bbf 100644 --- a/src/com/android/gallery3d/filtershow/controller/ColorChooser.java +++ b/src/com/android/gallery3d/filtershow/controller/ColorChooser.java @@ -68,9 +68,16 @@ public class ColorChooser implements Control { Color.colorToHSV(palette[i], hsvo); hsvo[OPACITY_OFFSET] = (0xFF & (palette[i] >> 24)) / (float) 255; button.setTag(hsvo); + + String colorString = "(" + Integer.toHexString(palette[i]) + ")"; + boolean colorSelect = false; + if (parameter.getValueString().equals(colorString)) { + mSelectedButton = i; + colorSelect = true; + } GradientDrawable sd = ((GradientDrawable) button.getBackground()); sd.setColor(palette[i]); - sd.setStroke(3, (mSelectedButton == i) ? mSelected : mTransparent); + sd.setStroke(3, colorSelect? mSelected : mTransparent); final int buttonNo = i; button.setOnClickListener(new View.OnClickListener() { diff --git a/src/com/android/gallery3d/filtershow/filters/FilterDrawRepresentation.java b/src/com/android/gallery3d/filtershow/filters/FilterDrawRepresentation.java index 48d3d9077..275a40409 100644 --- a/src/com/android/gallery3d/filtershow/filters/FilterDrawRepresentation.java +++ b/src/com/android/gallery3d/filtershow/filters/FilterDrawRepresentation.java @@ -166,6 +166,11 @@ public class FilterDrawRepresentation extends FilterRepresentation { setEditorId(EditorDraw.ID); setOverlayId(R.drawable.filtershow_drawing); setOverlayOnly(true); + setDefaultColor(); + } + + private void setDefaultColor() { + mParamColor.setValue(DEFAULT_MENU_COLOR1); } @Override -- cgit v1.2.3 From 078fa1b9f59dd8d6b72b3d86f0274c6ff0f20a27 Mon Sep 17 00:00:00 2001 From: kaiyiz Date: Thu, 8 Jan 2015 13:50:23 +0800 Subject: Gallery2: Set read only image unEditable When get the flag mReadOnlyView true, the menu item of edit is set true, which is not reasonable. Set the menu item of edit false if read only. CRs-Fixed: 768257 Change-Id: I88fb9a76036699b686ec14568ff54aba5523c5ec --- src/com/android/gallery3d/app/PhotoPage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/android/gallery3d/app/PhotoPage.java b/src/com/android/gallery3d/app/PhotoPage.java index bfd4528e4..07a07508d 100755 --- a/src/com/android/gallery3d/app/PhotoPage.java +++ b/src/com/android/gallery3d/app/PhotoPage.java @@ -819,7 +819,7 @@ public abstract class PhotoPage extends ActivityState implements int supportedOperations = mCurrentPhoto.getSupportedOperations(); if (mReadOnlyView) { - supportedOperations ^= MediaObject.SUPPORT_EDIT; + supportedOperations &= ~MediaObject.SUPPORT_EDIT; } if (mSecureAlbum != null) { supportedOperations &= MediaObject.SUPPORT_DELETE; -- cgit v1.2.3 From 787a6bb1167be8a58ccf3badce8fbf5d1163e1cc Mon Sep 17 00:00:00 2001 From: kaiyiz Date: Mon, 12 Jan 2015 11:44:32 +0800 Subject: Gallery2: Set APN setting intent's name The APN setting activity's name is changed, so there will be no result after tap prefered APN. Start intent with ACTION_APN_SETTINGS from settings. CRs-Fixed: 777155 Change-Id: Ibb560612ad5a6748c13319ed9436ad473759e3c1 --- src/org/codeaurora/gallery3d/video/SettingsActivity.java | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/org/codeaurora/gallery3d/video/SettingsActivity.java b/src/org/codeaurora/gallery3d/video/SettingsActivity.java index e2a60d49c..3d7fac573 100755 --- a/src/org/codeaurora/gallery3d/video/SettingsActivity.java +++ b/src/org/codeaurora/gallery3d/video/SettingsActivity.java @@ -286,22 +286,19 @@ public class SettingsActivity extends PreferenceActivity { } private void setApnListener() { - final String CLASS_NAME = "com.android.settings.ApnSettings"; final String SUBSCRIPTION_KEY = "subscription"; - mApn.setSummary(getDefaultApnName()); mApn.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { public boolean onPreferenceClick(Preference preference) { - Intent intent = new Intent(); - intent.setClassName(PACKAGE_NAME, CLASS_NAME); - + Intent intent = new Intent(Settings.ACTION_APN_SETTINGS); int subscription = 0; try { subscription = Settings.Global.getInt(SettingsActivity.this.getContentResolver(), Settings.Global.MULTI_SIM_DATA_CALL_SUBSCRIPTION); - intent.putExtra(SUBSCRIPTION_KEY, subscription); } catch (Exception e) { - Log.d("SettingActivity", "Can't get subscription for Exception" + e); + Log.d("SettingActivity", "Can't get subscription for Exception: " + e); + } finally { + intent.putExtra(SUBSCRIPTION_KEY, subscription); } startActivityForResult(intent, SELECT_APN); return true; -- cgit v1.2.3 From 9382a979292e52de5c60a39ba24688362dce8bc1 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 --- AndroidManifest.xml | 1 + res/drawable-hdpi/drm_image.png | Bin 0 -> 4378 bytes res/drawable-mdpi/drm_image.png | Bin 0 -> 3982 bytes res/drawable-xhdpi/drm_image.png | Bin 0 -> 5014 bytes res/menu/operation.xml | 5 + res/menu/photo.xml | 5 + res/values/strings.xml | 5 + 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 ++++- 30 files changed, 782 insertions(+), 35 deletions(-) create mode 100644 res/drawable-hdpi/drm_image.png create mode 100644 res/drawable-mdpi/drm_image.png create mode 100644 res/drawable-xhdpi/drm_image.png diff --git a/AndroidManifest.xml b/AndroidManifest.xml index b7960a26d..4c9bf20cb 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -172,6 +172,7 @@ + diff --git a/res/drawable-hdpi/drm_image.png b/res/drawable-hdpi/drm_image.png new file mode 100644 index 000000000..f51d615ee Binary files /dev/null and b/res/drawable-hdpi/drm_image.png differ diff --git a/res/drawable-mdpi/drm_image.png b/res/drawable-mdpi/drm_image.png new file mode 100644 index 000000000..dbbd7d8f0 Binary files /dev/null and b/res/drawable-mdpi/drm_image.png differ diff --git a/res/drawable-xhdpi/drm_image.png b/res/drawable-xhdpi/drm_image.png new file mode 100644 index 000000000..ff2877691 Binary files /dev/null and b/res/drawable-xhdpi/drm_image.png differ diff --git a/res/menu/operation.xml b/res/menu/operation.xml index d1791e22f..ffc5afa4a 100644 --- a/res/menu/operation.xml +++ b/res/menu/operation.xml @@ -70,4 +70,9 @@ android:title="@string/show_on_map" android:showAsAction="never" android:visible="false" /> + diff --git a/res/menu/photo.xml b/res/menu/photo.xml index bcd452e28..67e700b9f 100644 --- a/res/menu/photo.xml +++ b/res/menu/photo.xml @@ -78,4 +78,9 @@ + diff --git a/res/values/strings.xml b/res/values/strings.xml index 7fe8fb2e0..82b286b32 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -1147,4 +1147,9 @@ CHAR LIMIT = NONE] --> Sorry, this video file can not be trimmed Only mp4 and 3gp file can be trimmed + + "Sorry, Drm file can not be shared" + Drm license info + This file can not be played + Rights will be consumed for playing this media diff --git a/src/com/android/gallery3d/app/AlbumPage.java b/src/com/android/gallery3d/app/AlbumPage.java index 0614eef86..f6bb47d39 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"; @@ -100,7 +120,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; @@ -321,6 +342,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(); @@ -354,6 +438,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()); @@ -362,6 +447,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); @@ -404,6 +512,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 068ac33a0..f01585328 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 bb2a6b8f1..e04f8fdaf 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"; @@ -202,7 +211,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 8ee44402b..6aa4ce46b 100644 --- a/src/com/android/gallery3d/app/MovieActivity.java +++ b/src/com/android/gallery3d/app/MovieActivity.java @@ -26,6 +26,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; @@ -34,6 +37,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; @@ -47,6 +52,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; @@ -293,6 +299,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 07a07508d..2deab3234 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 fa709157d..b92e87712 100644 --- a/src/com/android/gallery3d/data/DecodeUtils.java +++ b/src/com/android/gallery3d/data/DecodeUtils.java @@ -85,7 +85,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, @@ -93,7 +93,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; } @@ -118,7 +118,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; @@ -146,7 +146,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 @@ -172,7 +172,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; @@ -182,8 +182,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 From cb07c05b9be20420b336d1d0cbc5e136f5d6337c Mon Sep 17 00:00:00 2001 From: kaiyiz Date: Fri, 16 Jan 2015 17:30:13 +0800 Subject: Gallery2: Fix Gallery2 crash caused by monkey test. It is NullPointerException which cause this bug happen. Add a condition to avoid NullPointerException. CRs-Fixed: 782023 Change-Id: Ia6d64a6c2a5aa47e3b13b69a26207d9384e40930 --- src/com/android/gallery3d/glrenderer/UploadedTexture.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/com/android/gallery3d/glrenderer/UploadedTexture.java b/src/com/android/gallery3d/glrenderer/UploadedTexture.java index f41a979b7..546d9f398 100644 --- a/src/com/android/gallery3d/glrenderer/UploadedTexture.java +++ b/src/com/android/gallery3d/glrenderer/UploadedTexture.java @@ -221,8 +221,11 @@ public abstract class UploadedTexture extends BasicTexture { Assert.assertTrue(bWidth <= texWidth && bHeight <= texHeight); - // Upload the bitmap to a new texture. - mId = canvas.getGLId().generateTexture(); + // Null pointer check here is to avoid monkey test failure. + if (canvas.getGLId() != null) { + // Upload the bitmap to a new texture. + mId = canvas.getGLId().generateTexture(); + } canvas.setTextureParameters(this); if (bWidth == texWidth && bHeight == texHeight) { -- cgit v1.2.3 From 9fca091600d01a8121c294dca590245e04221b20 Mon Sep 17 00:00:00 2001 From: kaiyiz Date: Wed, 21 Jan 2015 15:14:47 +0800 Subject: Gallery2: Edit picture during mount SD When SD card is mounted, the data of picture can't read to get mime type. As a result, there will be NullPointerException happen for the mimeType's value is null Change position of 'mimeType' and 'JPEG_MIME_TYPE', so that the judgement can go well without NullPointerException CRs-Fixed: 783875 Change-Id: I0d48b4ade06dba1c23a76b9046163a027f38e514 --- src/com/android/gallery3d/filtershow/tools/SaveImage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/android/gallery3d/filtershow/tools/SaveImage.java b/src/com/android/gallery3d/filtershow/tools/SaveImage.java index 24927f00c..94fed754f 100644 --- a/src/com/android/gallery3d/filtershow/tools/SaveImage.java +++ b/src/com/android/gallery3d/filtershow/tools/SaveImage.java @@ -247,7 +247,7 @@ public class SaveImage { if (mimeType == null) { mimeType = ImageLoader.getMimeType(mSelectedImageUri); } - if (mimeType.equals(ImageLoader.JPEG_MIME_TYPE)) { + if (ImageLoader.JPEG_MIME_TYPE.equals(mimeType)) { InputStream inStream = null; try { inStream = mContext.getContentResolver().openInputStream(source); -- cgit v1.2.3