blob: 5ccc21b93494c14481ba5785b307d9321455f0f4 [file] [log] [blame]
Owen Linf9a0a432011-08-17 22:07:43 +08001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.gallery3d.data;
18
Owen Linf9a0a432011-08-17 22:07:43 +080019import android.content.ContentResolver;
20import android.database.Cursor;
21import android.graphics.Bitmap;
Owen Linf9a0a432011-08-17 22:07:43 +080022import android.graphics.BitmapRegionDecoder;
Owen Linf9a0a432011-08-17 22:07:43 +080023import android.net.Uri;
24import android.provider.MediaStore.Video;
25import android.provider.MediaStore.Video.VideoColumns;
26
Owen Lin2b3ee0e2012-03-14 17:27:24 +080027import com.android.gallery3d.app.GalleryApp;
28import com.android.gallery3d.common.BitmapUtils;
29import com.android.gallery3d.util.GalleryUtils;
30import com.android.gallery3d.util.ThreadPool.Job;
31import com.android.gallery3d.util.ThreadPool.JobContext;
32import com.android.gallery3d.util.UpdateHelper;
Owen Linf9a0a432011-08-17 22:07:43 +080033
34// LocalVideo represents a video in the local storage.
35public class LocalVideo extends LocalMediaItem {
Chih-Chung Changf5ce6ae2012-05-11 17:55:02 +080036 private static final String TAG = "LocalVideo";
Owen Linf9a0a432011-08-17 22:07:43 +080037 static final Path ITEM_PATH = Path.fromString("/local/video/item");
38
39 // Must preserve order between these indices and the order of the terms in
40 // the following PROJECTION array.
41 private static final int INDEX_ID = 0;
42 private static final int INDEX_CAPTION = 1;
43 private static final int INDEX_MIME_TYPE = 2;
44 private static final int INDEX_LATITUDE = 3;
45 private static final int INDEX_LONGITUDE = 4;
46 private static final int INDEX_DATE_TAKEN = 5;
47 private static final int INDEX_DATE_ADDED = 6;
48 private static final int INDEX_DATE_MODIFIED = 7;
49 private static final int INDEX_DATA = 8;
50 private static final int INDEX_DURATION = 9;
51 private static final int INDEX_BUCKET_ID = 10;
Chih-Chung Changf5ce6ae2012-05-11 17:55:02 +080052 private static final int INDEX_SIZE = 11;
53 private static final int INDEX_RESOLUTION = 12;
Owen Linf9a0a432011-08-17 22:07:43 +080054
55 static final String[] PROJECTION = new String[] {
56 VideoColumns._ID,
57 VideoColumns.TITLE,
58 VideoColumns.MIME_TYPE,
59 VideoColumns.LATITUDE,
60 VideoColumns.LONGITUDE,
61 VideoColumns.DATE_TAKEN,
62 VideoColumns.DATE_ADDED,
63 VideoColumns.DATE_MODIFIED,
64 VideoColumns.DATA,
65 VideoColumns.DURATION,
66 VideoColumns.BUCKET_ID,
Chih-Chung Changf5ce6ae2012-05-11 17:55:02 +080067 VideoColumns.SIZE,
68 VideoColumns.RESOLUTION,
Owen Linf9a0a432011-08-17 22:07:43 +080069 };
70
71 private final GalleryApp mApplication;
Owen Linf9a0a432011-08-17 22:07:43 +080072
73 public int durationInSec;
74
75 public LocalVideo(Path path, GalleryApp application, Cursor cursor) {
76 super(path, nextVersionNumber());
77 mApplication = application;
78 loadFromCursor(cursor);
79 }
80
81 public LocalVideo(Path path, GalleryApp context, int id) {
82 super(path, nextVersionNumber());
83 mApplication = context;
84 ContentResolver resolver = mApplication.getContentResolver();
85 Uri uri = Video.Media.EXTERNAL_CONTENT_URI;
86 Cursor cursor = LocalAlbum.getItemCursor(resolver, uri, PROJECTION, id);
87 if (cursor == null) {
88 throw new RuntimeException("cannot get cursor for: " + path);
89 }
90 try {
91 if (cursor.moveToNext()) {
92 loadFromCursor(cursor);
93 } else {
94 throw new RuntimeException("cannot find data for: " + path);
95 }
96 } finally {
97 cursor.close();
98 }
99 }
100
101 private void loadFromCursor(Cursor cursor) {
102 id = cursor.getInt(INDEX_ID);
103 caption = cursor.getString(INDEX_CAPTION);
104 mimeType = cursor.getString(INDEX_MIME_TYPE);
105 latitude = cursor.getDouble(INDEX_LATITUDE);
106 longitude = cursor.getDouble(INDEX_LONGITUDE);
107 dateTakenInMs = cursor.getLong(INDEX_DATE_TAKEN);
108 filePath = cursor.getString(INDEX_DATA);
109 durationInSec = cursor.getInt(INDEX_DURATION) / 1000;
110 bucketId = cursor.getInt(INDEX_BUCKET_ID);
Chih-Chung Changf5ce6ae2012-05-11 17:55:02 +0800111 fileSize = cursor.getLong(INDEX_SIZE);
112 parseResolution(cursor.getString(INDEX_RESOLUTION));
113 }
114
115 private void parseResolution(String resolution) {
Chih-Chung Chang62c29e72012-05-17 23:44:54 -0700116 if (resolution == null) return;
Chih-Chung Changf5ce6ae2012-05-11 17:55:02 +0800117 int m = resolution.indexOf('x');
118 if (m == -1) return;
119 try {
120 int w = Integer.parseInt(resolution.substring(0, m));
121 int h = Integer.parseInt(resolution.substring(m + 1));
122 width = w;
123 height = h;
124 } catch (Throwable t) {
125 Log.w(TAG, t);
126 }
Owen Linf9a0a432011-08-17 22:07:43 +0800127 }
128
129 @Override
130 protected boolean updateFromCursor(Cursor cursor) {
131 UpdateHelper uh = new UpdateHelper();
132 id = uh.update(id, cursor.getInt(INDEX_ID));
133 caption = uh.update(caption, cursor.getString(INDEX_CAPTION));
134 mimeType = uh.update(mimeType, cursor.getString(INDEX_MIME_TYPE));
135 latitude = uh.update(latitude, cursor.getDouble(INDEX_LATITUDE));
136 longitude = uh.update(longitude, cursor.getDouble(INDEX_LONGITUDE));
137 dateTakenInMs = uh.update(
138 dateTakenInMs, cursor.getLong(INDEX_DATE_TAKEN));
139 dateAddedInSec = uh.update(
140 dateAddedInSec, cursor.getLong(INDEX_DATE_ADDED));
141 dateModifiedInSec = uh.update(
142 dateModifiedInSec, cursor.getLong(INDEX_DATE_MODIFIED));
143 filePath = uh.update(filePath, cursor.getString(INDEX_DATA));
144 durationInSec = uh.update(
145 durationInSec, cursor.getInt(INDEX_DURATION) / 1000);
146 bucketId = uh.update(bucketId, cursor.getInt(INDEX_BUCKET_ID));
Chih-Chung Changf5ce6ae2012-05-11 17:55:02 +0800147 fileSize = uh.update(fileSize, cursor.getLong(INDEX_SIZE));
Owen Linf9a0a432011-08-17 22:07:43 +0800148 return uh.isUpdated();
149 }
150
151 @Override
152 public Job<Bitmap> requestImage(int type) {
153 return new LocalVideoRequest(mApplication, getPath(), type, filePath);
154 }
155
156 public static class LocalVideoRequest extends ImageCacheRequest {
157 private String mLocalFilePath;
158
159 LocalVideoRequest(GalleryApp application, Path path, int type,
160 String localFilePath) {
Owen Lin4bb59122012-03-07 17:39:56 +0800161 super(application, path, type, MediaItem.getTargetSize(type));
Owen Linf9a0a432011-08-17 22:07:43 +0800162 mLocalFilePath = localFilePath;
163 }
164
165 @Override
166 public Bitmap onDecodeOriginal(JobContext jc, int type) {
167 Bitmap bitmap = BitmapUtils.createVideoThumbnail(mLocalFilePath);
168 if (bitmap == null || jc.isCancelled()) return null;
169 return bitmap;
170 }
171 }
172
173 @Override
174 public Job<BitmapRegionDecoder> requestLargeImage() {
175 throw new UnsupportedOperationException("Cannot regquest a large image"
176 + " to a local video!");
177 }
178
179 @Override
180 public int getSupportedOperations() {
181 return SUPPORT_DELETE | SUPPORT_SHARE | SUPPORT_PLAY | SUPPORT_INFO;
182 }
183
184 @Override
185 public void delete() {
186 GalleryUtils.assertNotInRenderThread();
187 Uri baseUri = Video.Media.EXTERNAL_CONTENT_URI;
188 mApplication.getContentResolver().delete(baseUri, "_id=?",
189 new String[]{String.valueOf(id)});
Chih-Chung Changc7e89da2012-06-26 19:12:09 +0800190 mApplication.getDataManager().broadcastLocalDeletion();
Owen Linf9a0a432011-08-17 22:07:43 +0800191 }
192
193 @Override
194 public void rotate(int degrees) {
195 // TODO
196 }
197
198 @Override
199 public Uri getContentUri() {
200 Uri baseUri = Video.Media.EXTERNAL_CONTENT_URI;
201 return baseUri.buildUpon().appendPath(String.valueOf(id)).build();
202 }
203
204 @Override
205 public Uri getPlayUri() {
Chih-Chung Chang25a329c2011-10-27 11:27:26 +0800206 return getContentUri();
Owen Linf9a0a432011-08-17 22:07:43 +0800207 }
208
209 @Override
210 public int getMediaType() {
211 return MEDIA_TYPE_VIDEO;
212 }
213
214 @Override
215 public MediaDetails getDetails() {
216 MediaDetails details = super.getDetails();
217 int s = durationInSec;
218 if (s > 0) {
219 details.addDetail(MediaDetails.INDEX_DURATION, GalleryUtils.formatDuration(
220 mApplication.getAndroidContext(), durationInSec));
221 }
222 return details;
223 }
Chih-Chung Changbc215412011-09-19 11:09:39 +0800224
225 @Override
226 public int getWidth() {
Chih-Chung Changf5ce6ae2012-05-11 17:55:02 +0800227 return width;
Chih-Chung Changbc215412011-09-19 11:09:39 +0800228 }
229
230 @Override
231 public int getHeight() {
Chih-Chung Changf5ce6ae2012-05-11 17:55:02 +0800232 return height;
Chih-Chung Changbc215412011-09-19 11:09:39 +0800233 }
Owen Linf9a0a432011-08-17 22:07:43 +0800234}