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