diff options
Diffstat (limited to 'src/com/android/gallery3d/provider/GalleryProvider.java')
-rw-r--r-- | src/com/android/gallery3d/provider/GalleryProvider.java | 224 |
1 files changed, 224 insertions, 0 deletions
diff --git a/src/com/android/gallery3d/provider/GalleryProvider.java b/src/com/android/gallery3d/provider/GalleryProvider.java new file mode 100644 index 000000000..f5f0f1b3c --- /dev/null +++ b/src/com/android/gallery3d/provider/GalleryProvider.java @@ -0,0 +1,224 @@ +/* + * Copyright (C) 2009 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.provider; + +import com.android.gallery3d.app.GalleryApp; +import com.android.gallery3d.common.Utils; +import com.android.gallery3d.data.DataManager; +import com.android.gallery3d.data.DownloadCache; +import com.android.gallery3d.data.MediaItem; +import com.android.gallery3d.data.MediaObject; +import com.android.gallery3d.data.MtpImage; +import com.android.gallery3d.data.Path; +import com.android.gallery3d.picasasource.PicasaSource; +import com.android.gallery3d.util.GalleryUtils; + +import android.content.ContentProvider; +import android.content.ContentValues; +import android.database.Cursor; +import android.database.MatrixCursor; +import android.net.Uri; +import android.os.Binder; +import android.os.Bundle; +import android.os.ParcelFileDescriptor; +import android.provider.MediaStore.Images.ImageColumns; +import android.util.Log; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.OutputStream; + +public class GalleryProvider extends ContentProvider { + private static final String TAG = "GalleryProvider"; + + public static final String AUTHORITY = "com.android.gallery3d.provider"; + public static final Uri BASE_URI = Uri.parse("content://" + AUTHORITY); + + private DataManager mDataManager; + private DownloadCache mDownloadCache; + + @Override + public int delete(Uri uri, String selection, String[] selectionArgs) { + throw new UnsupportedOperationException(); + } + + // TODO: consider concurrent access + @Override + public String getType(Uri uri) { + long token = Binder.clearCallingIdentity(); + try { + Path path = Path.fromString(uri.getPath()); + MediaItem item = (MediaItem) mDataManager.getMediaObject(path); + return item != null ? item.getMimeType() : null; + } finally { + Binder.restoreCallingIdentity(token); + } + } + + @Override + public Uri insert(Uri uri, ContentValues values) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean onCreate() { + GalleryApp app = (GalleryApp) getContext().getApplicationContext(); + mDataManager = app.getDataManager(); + return true; + } + + private DownloadCache getDownloadCache() { + if (mDownloadCache == null) { + GalleryApp app = (GalleryApp) getContext().getApplicationContext(); + mDownloadCache = app.getDownloadCache(); + } + return mDownloadCache; + } + + // TODO: consider concurrent access + @Override + public Cursor query(Uri uri, String[] projection, + String selection, String[] selectionArgs, String sortOrder) { + long token = Binder.clearCallingIdentity(); + try { + Path path = Path.fromString(uri.getPath()); + MediaObject object = mDataManager.getMediaObject(path); + if (object == null) { + Log.w(TAG, "cannot find: " + uri); + return null; + } + if (PicasaSource.isPicasaImage(object)) { + return queryPicasaItem(object, + projection, selection, selectionArgs, sortOrder); + } else if (object instanceof MtpImage) { + return queryMtpItem((MtpImage) object, + projection, selection, selectionArgs, sortOrder); + } else { + return null; + } + } finally { + Binder.restoreCallingIdentity(token); + } + } + + private Cursor queryMtpItem(MtpImage image, String[] projection, + String selection, String[] selectionArgs, String sortOrder) { + Object[] columnValues = new Object[projection.length]; + for (int i = 0, n = projection.length; i < n; ++i) { + String column = projection[i]; + if (ImageColumns.DISPLAY_NAME.equals(column)) { + columnValues[i] = image.getName(); + } else if (ImageColumns.SIZE.equals(column)){ + columnValues[i] = image.getSize(); + } else if (ImageColumns.MIME_TYPE.equals(column)) { + columnValues[i] = image.getMimeType(); + } else if (ImageColumns.DATE_TAKEN.equals(column)) { + columnValues[i] = image.getDateInMs(); + } else { + Log.w(TAG, "unsupported column: " + column); + } + } + MatrixCursor cursor = new MatrixCursor(projection); + cursor.addRow(columnValues); + return cursor; + } + + private Cursor queryPicasaItem(MediaObject image, String[] projection, + String selection, String[] selectionArgs, String sortOrder) { + Object[] columnValues = new Object[projection.length]; + double latitude = PicasaSource.getLatitude(image); + double longitude = PicasaSource.getLongitude(image); + boolean isValidLatlong = GalleryUtils.isValidLocation(latitude, longitude); + + for (int i = 0, n = projection.length; i < n; ++i) { + String column = projection[i]; + if (ImageColumns.DISPLAY_NAME.equals(column)) { + columnValues[i] = PicasaSource.getImageTitle(image); + } else if (ImageColumns.SIZE.equals(column)){ + columnValues[i] = PicasaSource.getImageSize(image); + } else if (ImageColumns.MIME_TYPE.equals(column)) { + columnValues[i] = PicasaSource.getContentType(image); + } else if (ImageColumns.DATE_TAKEN.equals(column)) { + columnValues[i] = PicasaSource.getDateTaken(image); + } else if (ImageColumns.LATITUDE.equals(column)) { + columnValues[i] = isValidLatlong ? latitude : null; + } else if (ImageColumns.LONGITUDE.equals(column)) { + columnValues[i] = isValidLatlong ? longitude : null; + } else if (ImageColumns.ORIENTATION.equals(column)) { + columnValues[i] = PicasaSource.getRotation(image); + } else { + Log.w(TAG, "unsupported column: " + column); + } + } + MatrixCursor cursor = new MatrixCursor(projection); + cursor.addRow(columnValues); + return cursor; + } + + @Override + public ParcelFileDescriptor openFile(Uri uri, String mode) + throws FileNotFoundException { + long token = Binder.clearCallingIdentity(); + try { + if (mode.contains("w")) { + throw new FileNotFoundException("cannot open file for write"); + } + Path path = Path.fromString(uri.getPath()); + MediaObject object = mDataManager.getMediaObject(path); + if (object == null) { + throw new FileNotFoundException(uri.toString()); + } + if (PicasaSource.isPicasaImage(object)) { + return PicasaSource.openFile(getContext(), object, mode); + } else if (object instanceof MtpImage) { + return openPipeHelper(uri, null, null, null, + new MtpPipeDataWriter((MtpImage) object)); + } else { + throw new FileNotFoundException("unspported type: " + object); + } + } finally { + Binder.restoreCallingIdentity(token); + } + } + + @Override + public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { + throw new UnsupportedOperationException(); + } + + private final class MtpPipeDataWriter implements PipeDataWriter<Object> { + private final MtpImage mImage; + + private MtpPipeDataWriter(MtpImage image) { + mImage = image; + } + + @Override + public void writeDataToPipe(ParcelFileDescriptor output, + Uri uri, String mimeType, Bundle opts, Object args) { + OutputStream os = null; + try { + os = new ParcelFileDescriptor.AutoCloseOutputStream(output); + os.write(mImage.getImageData()); + } catch (IOException e) { + Log.w(TAG, "fail to download: " + uri, e); + } finally { + Utils.closeSilently(os); + } + } + } +} |