summaryrefslogtreecommitdiffstats
path: root/src/com/android/gallery3d/data/LocalVideo.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/gallery3d/data/LocalVideo.java')
-rw-r--r--src/com/android/gallery3d/data/LocalVideo.java242
1 files changed, 242 insertions, 0 deletions
diff --git a/src/com/android/gallery3d/data/LocalVideo.java b/src/com/android/gallery3d/data/LocalVideo.java
new file mode 100644
index 000000000..4b8774ca4
--- /dev/null
+++ b/src/com/android/gallery3d/data/LocalVideo.java
@@ -0,0 +1,242 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.data;
+
+import android.content.ContentResolver;
+import android.database.Cursor;
+import android.graphics.Bitmap;
+import android.graphics.BitmapRegionDecoder;
+import android.net.Uri;
+import android.provider.MediaStore.Video;
+import android.provider.MediaStore.Video.VideoColumns;
+
+import com.android.gallery3d.app.GalleryApp;
+import com.android.gallery3d.common.BitmapUtils;
+import com.android.gallery3d.util.GalleryUtils;
+import com.android.gallery3d.util.ThreadPool.Job;
+import com.android.gallery3d.util.ThreadPool.JobContext;
+import com.android.gallery3d.util.UpdateHelper;
+
+// LocalVideo represents a video in the local storage.
+public class LocalVideo extends LocalMediaItem {
+ private static final String TAG = "LocalVideo";
+ static final Path ITEM_PATH = Path.fromString("/local/video/item");
+
+ // Must preserve order between these indices and the order of the terms in
+ // the following PROJECTION array.
+ private static final int INDEX_ID = 0;
+ private static final int INDEX_CAPTION = 1;
+ private static final int INDEX_MIME_TYPE = 2;
+ private static final int INDEX_LATITUDE = 3;
+ private static final int INDEX_LONGITUDE = 4;
+ private static final int INDEX_DATE_TAKEN = 5;
+ private static final int INDEX_DATE_ADDED = 6;
+ private static final int INDEX_DATE_MODIFIED = 7;
+ private static final int INDEX_DATA = 8;
+ private static final int INDEX_DURATION = 9;
+ private static final int INDEX_BUCKET_ID = 10;
+ private static final int INDEX_SIZE = 11;
+ private static final int INDEX_RESOLUTION = 12;
+
+ static final String[] PROJECTION = new String[] {
+ VideoColumns._ID,
+ VideoColumns.TITLE,
+ VideoColumns.MIME_TYPE,
+ VideoColumns.LATITUDE,
+ VideoColumns.LONGITUDE,
+ VideoColumns.DATE_TAKEN,
+ VideoColumns.DATE_ADDED,
+ VideoColumns.DATE_MODIFIED,
+ VideoColumns.DATA,
+ VideoColumns.DURATION,
+ VideoColumns.BUCKET_ID,
+ VideoColumns.SIZE,
+ VideoColumns.RESOLUTION,
+ };
+
+ private final GalleryApp mApplication;
+
+ public int durationInSec;
+
+ public LocalVideo(Path path, GalleryApp application, Cursor cursor) {
+ super(path, nextVersionNumber());
+ mApplication = application;
+ loadFromCursor(cursor);
+ }
+
+ public LocalVideo(Path path, GalleryApp context, int id) {
+ super(path, nextVersionNumber());
+ mApplication = context;
+ ContentResolver resolver = mApplication.getContentResolver();
+ Uri uri = Video.Media.EXTERNAL_CONTENT_URI;
+ Cursor cursor = LocalAlbum.getItemCursor(resolver, uri, PROJECTION, id);
+ if (cursor == null) {
+ throw new RuntimeException("cannot get cursor for: " + path);
+ }
+ try {
+ if (cursor.moveToNext()) {
+ loadFromCursor(cursor);
+ } else {
+ throw new RuntimeException("cannot find data for: " + path);
+ }
+ } finally {
+ cursor.close();
+ }
+ }
+
+ private void loadFromCursor(Cursor cursor) {
+ id = cursor.getInt(INDEX_ID);
+ caption = cursor.getString(INDEX_CAPTION);
+ mimeType = cursor.getString(INDEX_MIME_TYPE);
+ latitude = cursor.getDouble(INDEX_LATITUDE);
+ longitude = cursor.getDouble(INDEX_LONGITUDE);
+ dateTakenInMs = cursor.getLong(INDEX_DATE_TAKEN);
+ dateAddedInSec = cursor.getLong(INDEX_DATE_ADDED);
+ dateModifiedInSec = cursor.getLong(INDEX_DATE_MODIFIED);
+ filePath = cursor.getString(INDEX_DATA);
+ durationInSec = cursor.getInt(INDEX_DURATION) / 1000;
+ bucketId = cursor.getInt(INDEX_BUCKET_ID);
+ fileSize = cursor.getLong(INDEX_SIZE);
+ parseResolution(cursor.getString(INDEX_RESOLUTION));
+ }
+
+ private void parseResolution(String resolution) {
+ if (resolution == null) return;
+ int m = resolution.indexOf('x');
+ if (m == -1) return;
+ try {
+ int w = Integer.parseInt(resolution.substring(0, m));
+ int h = Integer.parseInt(resolution.substring(m + 1));
+ width = w;
+ height = h;
+ } catch (Throwable t) {
+ Log.w(TAG, t);
+ }
+ }
+
+ @Override
+ protected boolean updateFromCursor(Cursor cursor) {
+ UpdateHelper uh = new UpdateHelper();
+ id = uh.update(id, cursor.getInt(INDEX_ID));
+ caption = uh.update(caption, cursor.getString(INDEX_CAPTION));
+ mimeType = uh.update(mimeType, cursor.getString(INDEX_MIME_TYPE));
+ latitude = uh.update(latitude, cursor.getDouble(INDEX_LATITUDE));
+ longitude = uh.update(longitude, cursor.getDouble(INDEX_LONGITUDE));
+ dateTakenInMs = uh.update(
+ dateTakenInMs, cursor.getLong(INDEX_DATE_TAKEN));
+ dateAddedInSec = uh.update(
+ dateAddedInSec, cursor.getLong(INDEX_DATE_ADDED));
+ dateModifiedInSec = uh.update(
+ dateModifiedInSec, cursor.getLong(INDEX_DATE_MODIFIED));
+ filePath = uh.update(filePath, cursor.getString(INDEX_DATA));
+ durationInSec = uh.update(
+ durationInSec, cursor.getInt(INDEX_DURATION) / 1000);
+ bucketId = uh.update(bucketId, cursor.getInt(INDEX_BUCKET_ID));
+ fileSize = uh.update(fileSize, cursor.getLong(INDEX_SIZE));
+ return uh.isUpdated();
+ }
+
+ @Override
+ public Job<Bitmap> requestImage(int type) {
+ return new LocalVideoRequest(mApplication, getPath(), dateModifiedInSec,
+ type, filePath);
+ }
+
+ public static class LocalVideoRequest extends ImageCacheRequest {
+ private String mLocalFilePath;
+
+ LocalVideoRequest(GalleryApp application, Path path, long timeModified,
+ int type, String localFilePath) {
+ super(application, path, timeModified, type,
+ MediaItem.getTargetSize(type));
+ mLocalFilePath = localFilePath;
+ }
+
+ @Override
+ public Bitmap onDecodeOriginal(JobContext jc, int type) {
+ Bitmap bitmap = BitmapUtils.createVideoThumbnail(mLocalFilePath);
+ if (bitmap == null || jc.isCancelled()) return null;
+ return bitmap;
+ }
+ }
+
+ @Override
+ public Job<BitmapRegionDecoder> requestLargeImage() {
+ throw new UnsupportedOperationException("Cannot regquest a large image"
+ + " to a local video!");
+ }
+
+ @Override
+ public int getSupportedOperations() {
+ return SUPPORT_DELETE | SUPPORT_SHARE | SUPPORT_PLAY | SUPPORT_INFO | SUPPORT_TRIM | SUPPORT_MUTE;
+ }
+
+ @Override
+ public void delete() {
+ GalleryUtils.assertNotInRenderThread();
+ Uri baseUri = Video.Media.EXTERNAL_CONTENT_URI;
+ mApplication.getContentResolver().delete(baseUri, "_id=?",
+ new String[]{String.valueOf(id)});
+ }
+
+ @Override
+ public void rotate(int degrees) {
+ // TODO
+ }
+
+ @Override
+ public Uri getContentUri() {
+ Uri baseUri = Video.Media.EXTERNAL_CONTENT_URI;
+ return baseUri.buildUpon().appendPath(String.valueOf(id)).build();
+ }
+
+ @Override
+ public Uri getPlayUri() {
+ return getContentUri();
+ }
+
+ @Override
+ public int getMediaType() {
+ return MEDIA_TYPE_VIDEO;
+ }
+
+ @Override
+ public MediaDetails getDetails() {
+ MediaDetails details = super.getDetails();
+ int s = durationInSec;
+ if (s > 0) {
+ details.addDetail(MediaDetails.INDEX_DURATION, GalleryUtils.formatDuration(
+ mApplication.getAndroidContext(), durationInSec));
+ }
+ return details;
+ }
+
+ @Override
+ public int getWidth() {
+ return width;
+ }
+
+ @Override
+ public int getHeight() {
+ return height;
+ }
+
+ @Override
+ public String getFilePath() {
+ return filePath;
+ }
+}