1f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin/* 2f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Copyright (C) 2010 The Android Open Source Project 3f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * 4f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Licensed under the Apache License, Version 2.0 (the "License"); 5f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * you may not use this file except in compliance with the License. 6f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * You may obtain a copy of the License at 7f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * 8f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * http://www.apache.org/licenses/LICENSE-2.0 9f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * 10f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Unless required by applicable law or agreed to in writing, software 11f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * distributed under the License is distributed on an "AS IS" BASIS, 12f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * See the License for the specific language governing permissions and 14f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * limitations under the License. 15f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin */ 16f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 17f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linpackage com.android.gallery3d.data; 18f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 19d43ea8bb1b1afcb27c1c6c673c8ed2707bc70ff0Owen Linimport android.annotation.TargetApi; 20476a89e18fc6b8a472b4e352d20be3a09a1776a4Owen Linimport android.content.Context; 21f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.graphics.Bitmap; 22f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.graphics.BitmapRegionDecoder; 23f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.hardware.usb.UsbDevice; 24f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.mtp.MtpObjectInfo; 25f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.net.Uri; 26f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.util.Log; 27f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 282b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Linimport com.android.gallery3d.app.GalleryApp; 29d43ea8bb1b1afcb27c1c6c673c8ed2707bc70ff0Owen Linimport com.android.gallery3d.common.ApiHelper; 302b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Linimport com.android.gallery3d.provider.GalleryProvider; 312b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Linimport com.android.gallery3d.util.ThreadPool.Job; 322b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Linimport com.android.gallery3d.util.ThreadPool.JobContext; 332b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Lin 34f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport java.text.DateFormat; 35f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport java.util.Date; 36f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 37d43ea8bb1b1afcb27c1c6c673c8ed2707bc70ff0Owen Lin@TargetApi(ApiHelper.VERSION_CODES.HONEYCOMB_MR1) 38f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linpublic class MtpImage extends MediaItem { 39f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static final String TAG = "MtpImage"; 40f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 41f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private final int mDeviceId; 42f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private int mObjectId; 43f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private int mObjectSize; 44f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private long mDateTaken; 45f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private String mFileName; 46f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private final MtpContext mMtpContext; 47f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private final MtpObjectInfo mObjInfo; 48f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private final int mImageWidth; 49f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private final int mImageHeight; 50476a89e18fc6b8a472b4e352d20be3a09a1776a4Owen Lin private final Context mContext; 51f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 52f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin MtpImage(Path path, GalleryApp application, int deviceId, 53f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin MtpObjectInfo objInfo, MtpContext mtpContext) { 54f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin super(path, nextVersionNumber()); 55476a89e18fc6b8a472b4e352d20be3a09a1776a4Owen Lin mContext = application.getAndroidContext(); 56f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mDeviceId = deviceId; 57f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mObjInfo = objInfo; 58f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mObjectId = objInfo.getObjectHandle(); 59f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mObjectSize = objInfo.getCompressedSize(); 60f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mDateTaken = objInfo.getDateCreated(); 61f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mFileName = objInfo.getName(); 62f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mImageWidth = objInfo.getImagePixWidth(); 63f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mImageHeight = objInfo.getImagePixHeight(); 64f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mMtpContext = mtpContext; 65f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 66f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 67f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin MtpImage(Path path, GalleryApp app, int deviceId, int objectId, MtpContext mtpContext) { 68f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin this(path, app, deviceId, MtpDevice.getObjectInfo(mtpContext, deviceId, objectId), 69f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mtpContext); 70f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 71f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 72f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 73f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public long getDateInMs() { 74f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return mDateTaken; 75f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 76f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 77f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 78f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public Job<Bitmap> requestImage(int type) { 79f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return new Job<Bitmap>() { 807817979db0c52ffeacb951625b1e821eba303285Ahbong Chang @Override 81f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public Bitmap run(JobContext jc) { 828da5fdfe8f8d15aa688e504afd3ede2555de8bdeRay Chen byte[] thumbnail = mMtpContext.getMtpClient().getThumbnail( 838da5fdfe8f8d15aa688e504afd3ede2555de8bdeRay Chen UsbDevice.getDeviceName(mDeviceId), mObjectId); 84f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (thumbnail == null) { 85f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Log.w(TAG, "decoding thumbnail failed"); 86f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return null; 87f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 884bb5912e85f6d1bd8a6b78d6d52b4c4da7aeb740Owen Lin return DecodeUtils.decode(jc, thumbnail, null); 89f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 90f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin }; 91f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 92f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 93f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 94f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public Job<BitmapRegionDecoder> requestLargeImage() { 95f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return new Job<BitmapRegionDecoder>() { 967817979db0c52ffeacb951625b1e821eba303285Ahbong Chang @Override 97f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public BitmapRegionDecoder run(JobContext jc) { 98f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin byte[] bytes = mMtpContext.getMtpClient().getObject( 99f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin UsbDevice.getDeviceName(mDeviceId), mObjectId, mObjectSize); 1004bb5912e85f6d1bd8a6b78d6d52b4c4da7aeb740Owen Lin return DecodeUtils.createBitmapRegionDecoder( 101f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin jc, bytes, 0, bytes.length, false); 102f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 103f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin }; 104f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 105f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 106f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public byte[] getImageData() { 107f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return mMtpContext.getMtpClient().getObject( 108f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin UsbDevice.getDeviceName(mDeviceId), mObjectId, mObjectSize); 109f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 110f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 111f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 112f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public boolean Import() { 113f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return mMtpContext.copyFile(UsbDevice.getDeviceName(mDeviceId), mObjInfo); 114f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 115f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 116f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 117f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public int getSupportedOperations() { 118f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return SUPPORT_FULL_IMAGE | SUPPORT_IMPORT; 119f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 120f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 121f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void updateContent(MtpObjectInfo info) { 122f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mObjectId != info.getObjectHandle() || mDateTaken != info.getDateCreated()) { 123f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mObjectId = info.getObjectHandle(); 124f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mDateTaken = info.getDateCreated(); 125f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mDataVersion = nextVersionNumber(); 126f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 127f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 128f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 129f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 130f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public String getMimeType() { 131f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // Currently only JPEG is supported in MTP. 132f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return "image/jpeg"; 133f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 134f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 135f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 136f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public int getMediaType() { 137f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return MEDIA_TYPE_IMAGE; 138f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 139f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 140f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 141f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public long getSize() { 142f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return mObjectSize; 143f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 144f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 145f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 146f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public Uri getContentUri() { 147476a89e18fc6b8a472b4e352d20be3a09a1776a4Owen Lin return GalleryProvider.getUriFor(mContext, mPath); 148f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 149f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 150f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 151f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public MediaDetails getDetails() { 152f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin MediaDetails details = super.getDetails(); 153f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin DateFormat formater = DateFormat.getDateTimeInstance(); 154f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin details.addDetail(MediaDetails.INDEX_TITLE, mFileName); 155f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin details.addDetail(MediaDetails.INDEX_DATETIME, formater.format(new Date(mDateTaken))); 156f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin details.addDetail(MediaDetails.INDEX_WIDTH, mImageWidth); 157f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin details.addDetail(MediaDetails.INDEX_HEIGHT, mImageHeight); 158f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin details.addDetail(MediaDetails.INDEX_SIZE, Long.valueOf(mObjectSize)); 159f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return details; 160f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 161f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 162bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang @Override 163bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang public int getWidth() { 164bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang return mImageWidth; 165bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang } 166bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang 167bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang @Override 168bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang public int getHeight() { 169bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang return mImageHeight; 170bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang } 171f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin} 172