MtpImageView.java revision baa68886db66f4beb6a07e4441b122975b778f1c
1c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu/*
2c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu * Copyright (C) 2013 The Android Open Source Project
3c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu *
4c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu * Licensed under the Apache License, Version 2.0 (the "License");
5c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu * you may not use this file except in compliance with the License.
6c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu * You may obtain a copy of the License at
7c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu *
8c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu *      http://www.apache.org/licenses/LICENSE-2.0
9c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu *
10c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu * Unless required by applicable law or agreed to in writing, software
11c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu * distributed under the License is distributed on an "AS IS" BASIS,
12c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu * See the License for the specific language governing permissions and
14c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu * limitations under the License.
15c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu */
16c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu
17c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescupackage com.android.gallery3d.ingest.ui;
18c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu
19c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescuimport android.content.Context;
20573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescuimport android.graphics.Matrix;
21c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescuimport android.mtp.MtpDevice;
22c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescuimport android.mtp.MtpObjectInfo;
2337faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescuimport android.os.Handler;
2437faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescuimport android.os.HandlerThread;
2537faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescuimport android.os.Looper;
2637faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescuimport android.os.Message;
27c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescuimport android.util.AttributeSet;
28c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescuimport android.widget.ImageView;
29c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu
30baa68886db66f4beb6a07e4441b122975b778f1cBobby Georgescuimport com.android.gallery3d.ingest.MtpDeviceIndex;
31c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescuimport com.android.gallery3d.ingest.data.BitmapWithMetadata;
32c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescuimport com.android.gallery3d.ingest.data.MtpBitmapFetch;
33c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu
3437faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescuimport java.lang.ref.WeakReference;
35c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu
3637faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescupublic class MtpImageView extends ImageView {
37baa68886db66f4beb6a07e4441b122975b778f1cBobby Georgescu    // We will use the thumbnail for images larger than this threshold
38baa68886db66f4beb6a07e4441b122975b778f1cBobby Georgescu    private static final int MAX_FULLSIZE_PREVIEW_SIZE = 8388608; // 8 megabytes
39baa68886db66f4beb6a07e4441b122975b778f1cBobby Georgescu
40c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu    private int mObjectHandle;
41c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu    private int mGeneration;
42c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu
4337faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu    private WeakReference<MtpImageView> mWeakReference = new WeakReference<MtpImageView>(this);
4437faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu    private Object mFetchLock = new Object();
4537faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu    private boolean mFetchPending = false;
4637faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu    private MtpObjectInfo mFetchObjectInfo;
4737faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu    private MtpDevice mFetchDevice;
4837faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu    private Object mFetchResult;
4937faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu
5037faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu    private static final FetchImageHandler sFetchHandler = FetchImageHandler.createOnNewThread();
5137faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu    private static final ShowImageHandler sFetchCompleteHandler = new ShowImageHandler();
5237faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu
53c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu    private void init() {
54c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu         showPlaceholder();
55c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu    }
56c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu
57c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu    public MtpImageView(Context context) {
58c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu        super(context);
59c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu        init();
60c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu    }
61c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu
62c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu    public MtpImageView(Context context, AttributeSet attrs) {
63c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu        super(context, attrs);
64c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu        init();
65c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu    }
66c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu
67c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu    public MtpImageView(Context context, AttributeSet attrs, int defStyle) {
68c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu        super(context, attrs, defStyle);
69c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu        init();
70c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu    }
71c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu
72c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu    private void showPlaceholder() {
73c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu        setImageResource(android.R.color.transparent);
74c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu    }
75c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu
76c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu    public void setMtpDeviceAndObjectInfo(MtpDevice device, MtpObjectInfo object, int gen) {
77c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu        int handle = object.getObjectHandle();
78c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu        if (handle == mObjectHandle && gen == mGeneration) {
79c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu            return;
80c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu        }
81c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu        cancelLoadingAndClear();
82c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu        showPlaceholder();
83c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu        mGeneration = gen;
84c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu        mObjectHandle = handle;
8537faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu        synchronized (mFetchLock) {
8637faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            mFetchObjectInfo = object;
8737faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            mFetchDevice = device;
8837faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            if (mFetchPending) return;
8937faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            mFetchPending = true;
9037faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            sFetchHandler.sendMessage(
9137faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu                    sFetchHandler.obtainMessage(0, mWeakReference));
9237faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu        }
93c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu    }
94c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu
95c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu    protected Object fetchMtpImageDataFromDevice(MtpDevice device, MtpObjectInfo info) {
96baa68886db66f4beb6a07e4441b122975b778f1cBobby Georgescu        if (info.getCompressedSize() <= MAX_FULLSIZE_PREVIEW_SIZE
97baa68886db66f4beb6a07e4441b122975b778f1cBobby Georgescu                && MtpDeviceIndex.SUPPORTED_IMAGE_FORMATS.contains(info.getFormat())) {
98baa68886db66f4beb6a07e4441b122975b778f1cBobby Georgescu            return MtpBitmapFetch.getFullsize(device, info);
99baa68886db66f4beb6a07e4441b122975b778f1cBobby Georgescu        } else {
100baa68886db66f4beb6a07e4441b122975b778f1cBobby Georgescu            return new BitmapWithMetadata(MtpBitmapFetch.getThumbnail(device, info), 0);
101baa68886db66f4beb6a07e4441b122975b778f1cBobby Georgescu        }
102c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu    }
103c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu
104573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu    private float mLastBitmapWidth;
105573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu    private float mLastBitmapHeight;
106573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu    private int mLastRotationDegrees;
107573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu    private Matrix mDrawMatrix = new Matrix();
108573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu
109573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu    private void updateDrawMatrix() {
110573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu        mDrawMatrix.reset();
111573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu        float dwidth;
112573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu        float dheight;
113573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu        float vheight = getHeight();
114573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu        float vwidth = getWidth();
115573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu        float scale;
116573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu        boolean rotated90 = (mLastRotationDegrees % 180 != 0);
117573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu        if (rotated90) {
118573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu            dwidth = mLastBitmapHeight;
119573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu            dheight = mLastBitmapWidth;
120573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu        } else {
121573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu            dwidth = mLastBitmapWidth;
122573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu            dheight = mLastBitmapHeight;
123573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu        }
124573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu        if (dwidth <= vwidth && dheight <= vheight) {
125573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu            scale = 1.0f;
126573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu        } else {
127573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu            scale = Math.min(vwidth / dwidth, vheight / dheight);
128573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu        }
129573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu        mDrawMatrix.setScale(scale, scale);
130573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu        if (rotated90) {
131573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu            mDrawMatrix.postTranslate(-dheight * scale * 0.5f,
132573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu                    -dwidth * scale * 0.5f);
133573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu            mDrawMatrix.postRotate(mLastRotationDegrees);
134573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu            mDrawMatrix.postTranslate(dwidth * scale * 0.5f,
135573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu                    dheight * scale * 0.5f);
136573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu        }
137573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu        mDrawMatrix.postTranslate((vwidth - dwidth * scale) * 0.5f,
138573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu                (vheight - dheight * scale) * 0.5f);
139573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu        if (!rotated90 && mLastRotationDegrees > 0) {
140573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu            // rotated by a multiple of 180
141573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu            mDrawMatrix.postRotate(mLastRotationDegrees, vwidth / 2, vheight / 2);
142573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu        }
143573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu        setImageMatrix(mDrawMatrix);
144573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu    }
145573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu
146573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu    @Override
147573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
148573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu        super.onLayout(changed, left, top, right, bottom);
149573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu        if (changed && getScaleType() == ScaleType.MATRIX) {
150573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu            updateDrawMatrix();
151573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu        }
152573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu    }
153573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu
154c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu    protected void onMtpImageDataFetchedFromDevice(Object result) {
155c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu        BitmapWithMetadata bitmapWithMetadata = (BitmapWithMetadata)result;
156573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu        if (getScaleType() == ScaleType.MATRIX) {
157573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu            mLastBitmapHeight = bitmapWithMetadata.bitmap.getHeight();
158573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu            mLastBitmapWidth = bitmapWithMetadata.bitmap.getWidth();
159573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu            mLastRotationDegrees = bitmapWithMetadata.rotationDegrees;
160573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu            updateDrawMatrix();
161573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu        } else {
162573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu            setRotation(bitmapWithMetadata.rotationDegrees);
163573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu        }
1640683fe0a1c913d6cc48a127bf6a1486422d1b040Bobby Georgescu        setAlpha(0f);
165c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu        setImageBitmap(bitmapWithMetadata.bitmap);
1660683fe0a1c913d6cc48a127bf6a1486422d1b040Bobby Georgescu        animate().alpha(1f);
167c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu    }
168c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu
16937faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu    protected void cancelLoadingAndClear() {
17037faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu        synchronized (mFetchLock) {
17137faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            mFetchDevice = null;
17237faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            mFetchObjectInfo = null;
17337faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            mFetchResult = null;
174c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu        }
1750683fe0a1c913d6cc48a127bf6a1486422d1b040Bobby Georgescu        animate().cancel();
17637faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu        setImageResource(android.R.color.transparent);
17737faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu    }
178c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu
17937faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu    @Override
18037faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu    public void onDetachedFromWindow() {
18137faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu        cancelLoadingAndClear();
18237faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu        super.onDetachedFromWindow();
18337faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu    }
18437faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu
18537faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu    private static class FetchImageHandler extends Handler {
18637faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu        public FetchImageHandler(Looper l) {
18737faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            super(l);
188c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu        }
189c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu
19037faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu        public static FetchImageHandler createOnNewThread() {
19137faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            HandlerThread t = new HandlerThread("MtpImageView Fetch");
19237faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            t.start();
19337faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            return new FetchImageHandler(t.getLooper());
194c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu        }
195c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu
196c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu        @Override
19737faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu        public void handleMessage(Message msg) {
19837faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            @SuppressWarnings("unchecked")
19937faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            MtpImageView parent = ((WeakReference<MtpImageView>) msg.obj).get();
20037faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            if (parent == null) return;
20137faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            MtpObjectInfo objectInfo;
20237faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            MtpDevice device;
20337faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            synchronized (parent.mFetchLock) {
20437faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu                parent.mFetchPending = false;
20537faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu                device = parent.mFetchDevice;
20637faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu                objectInfo = parent.mFetchObjectInfo;
20737faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            }
20837faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            if (device == null) return;
20937faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            Object result = parent.fetchMtpImageDataFromDevice(device, objectInfo);
21037faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            if (result == null) return;
21137faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            synchronized (parent.mFetchLock) {
21237faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu                if (parent.mFetchObjectInfo != objectInfo) return;
21337faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu                parent.mFetchResult = result;
21437faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu                parent.mFetchDevice = null;
21537faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu                parent.mFetchObjectInfo = null;
21637faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu                sFetchCompleteHandler.sendMessage(
21737faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu                        sFetchCompleteHandler.obtainMessage(0, parent.mWeakReference));
21837faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            }
219c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu        }
220c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu    }
221c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu
22237faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu    private static class ShowImageHandler extends Handler {
22337faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu        @Override
22437faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu        public void handleMessage(Message msg) {
22537faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            @SuppressWarnings("unchecked")
22637faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            MtpImageView parent = ((WeakReference<MtpImageView>) msg.obj).get();
22737faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            if (parent == null) return;
22837faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            Object result;
22937faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            synchronized (parent.mFetchLock) {
23037faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu                result = parent.mFetchResult;
23137faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            }
23237faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            if (result == null) return;
23337faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            parent.onMtpImageDataFetchedFromDevice(result);
234c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu        }
235c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu    }
236c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu}
237