blob: 5b6ee4b33aa3f0c1767409fbcd4570db622ba9e6 [file] [log] [blame]
/*
* 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);
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(), type, filePath);
}
public static class LocalVideoRequest extends ImageCacheRequest {
private String mLocalFilePath;
LocalVideoRequest(GalleryApp application, Path path, int type,
String localFilePath) {
super(application, path, 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;
}
@Override
public void delete() {
GalleryUtils.assertNotInRenderThread();
Uri baseUri = Video.Media.EXTERNAL_CONTENT_URI;
mApplication.getContentResolver().delete(baseUri, "_id=?",
new String[]{String.valueOf(id)});
mApplication.getDataManager().broadcastLocalDeletion();
}
@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;
}
}