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
30c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescuimport com.android.gallery3d.ingest.data.BitmapWithMetadata;
31c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescuimport com.android.gallery3d.ingest.data.MtpBitmapFetch;
32c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu
3337faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescuimport java.lang.ref.WeakReference;
34c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu
3537faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescupublic class MtpImageView extends ImageView {
36c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu    private int mObjectHandle;
37c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu    private int mGeneration;
38c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu
3937faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu    private WeakReference<MtpImageView> mWeakReference = new WeakReference<MtpImageView>(this);
4037faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu    private Object mFetchLock = new Object();
4137faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu    private boolean mFetchPending = false;
4237faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu    private MtpObjectInfo mFetchObjectInfo;
4337faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu    private MtpDevice mFetchDevice;
4437faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu    private Object mFetchResult;
4537faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu
4637faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu    private static final FetchImageHandler sFetchHandler = FetchImageHandler.createOnNewThread();
4737faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu    private static final ShowImageHandler sFetchCompleteHandler = new ShowImageHandler();
4837faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu
49c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu    private void init() {
50c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu         showPlaceholder();
51c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu    }
52c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu
53c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu    public MtpImageView(Context context) {
54c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu        super(context);
55c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu        init();
56c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu    }
57c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu
58c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu    public MtpImageView(Context context, AttributeSet attrs) {
59c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu        super(context, attrs);
60c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu        init();
61c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu    }
62c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu
63c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu    public MtpImageView(Context context, AttributeSet attrs, int defStyle) {
64c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu        super(context, attrs, defStyle);
65c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu        init();
66c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu    }
67c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu
68c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu    private void showPlaceholder() {
69c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu        setImageResource(android.R.color.transparent);
70c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu    }
71c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu
72c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu    public void setMtpDeviceAndObjectInfo(MtpDevice device, MtpObjectInfo object, int gen) {
73c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu        int handle = object.getObjectHandle();
74c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu        if (handle == mObjectHandle && gen == mGeneration) {
75c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu            return;
76c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu        }
77c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu        cancelLoadingAndClear();
78c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu        showPlaceholder();
79c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu        mGeneration = gen;
80c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu        mObjectHandle = handle;
8137faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu        synchronized (mFetchLock) {
8237faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            mFetchObjectInfo = object;
8337faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            mFetchDevice = device;
8437faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            if (mFetchPending) return;
8537faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            mFetchPending = true;
8637faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            sFetchHandler.sendMessage(
8737faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu                    sFetchHandler.obtainMessage(0, mWeakReference));
8837faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu        }
89c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu    }
90c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu
91c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu    protected Object fetchMtpImageDataFromDevice(MtpDevice device, MtpObjectInfo info) {
92c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu        return MtpBitmapFetch.getFullsize(device, info);
93c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu    }
94c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu
95573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu    private float mLastBitmapWidth;
96573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu    private float mLastBitmapHeight;
97573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu    private int mLastRotationDegrees;
98573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu    private Matrix mDrawMatrix = new Matrix();
99573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu
100573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu    private void updateDrawMatrix() {
101573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu        mDrawMatrix.reset();
102573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu        float dwidth;
103573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu        float dheight;
104573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu        float vheight = getHeight();
105573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu        float vwidth = getWidth();
106573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu        float scale;
107573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu        boolean rotated90 = (mLastRotationDegrees % 180 != 0);
108573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu        if (rotated90) {
109573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu            dwidth = mLastBitmapHeight;
110573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu            dheight = mLastBitmapWidth;
111573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu        } else {
112573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu            dwidth = mLastBitmapWidth;
113573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu            dheight = mLastBitmapHeight;
114573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu        }
115573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu        if (dwidth <= vwidth && dheight <= vheight) {
116573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu            scale = 1.0f;
117573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu        } else {
118573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu            scale = Math.min(vwidth / dwidth, vheight / dheight);
119573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu        }
120573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu        mDrawMatrix.setScale(scale, scale);
121573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu        if (rotated90) {
122573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu            mDrawMatrix.postTranslate(-dheight * scale * 0.5f,
123573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu                    -dwidth * scale * 0.5f);
124573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu            mDrawMatrix.postRotate(mLastRotationDegrees);
125573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu            mDrawMatrix.postTranslate(dwidth * scale * 0.5f,
126573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu                    dheight * scale * 0.5f);
127573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu        }
128573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu        mDrawMatrix.postTranslate((vwidth - dwidth * scale) * 0.5f,
129573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu                (vheight - dheight * scale) * 0.5f);
130573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu        if (!rotated90 && mLastRotationDegrees > 0) {
131573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu            // rotated by a multiple of 180
132573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu            mDrawMatrix.postRotate(mLastRotationDegrees, vwidth / 2, vheight / 2);
133573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu        }
134573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu        setImageMatrix(mDrawMatrix);
135573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu    }
136573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu
137573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu    @Override
138573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
139573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu        super.onLayout(changed, left, top, right, bottom);
140573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu        if (changed && getScaleType() == ScaleType.MATRIX) {
141573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu            updateDrawMatrix();
142573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu        }
143573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu    }
144573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu
145c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu    protected void onMtpImageDataFetchedFromDevice(Object result) {
146c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu        BitmapWithMetadata bitmapWithMetadata = (BitmapWithMetadata)result;
147573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu        if (getScaleType() == ScaleType.MATRIX) {
148573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu            mLastBitmapHeight = bitmapWithMetadata.bitmap.getHeight();
149573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu            mLastBitmapWidth = bitmapWithMetadata.bitmap.getWidth();
150573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu            mLastRotationDegrees = bitmapWithMetadata.rotationDegrees;
151573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu            updateDrawMatrix();
152573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu        } else {
153573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu            setRotation(bitmapWithMetadata.rotationDegrees);
154573dfae59a96663b6ff6e47b4c7db326c651a3cfBobby Georgescu        }
1550683fe0a1c913d6cc48a127bf6a1486422d1b040Bobby Georgescu        setAlpha(0f);
156c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu        setImageBitmap(bitmapWithMetadata.bitmap);
1570683fe0a1c913d6cc48a127bf6a1486422d1b040Bobby Georgescu        animate().alpha(1f);
158c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu    }
159c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu
16037faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu    protected void cancelLoadingAndClear() {
16137faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu        synchronized (mFetchLock) {
16237faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            mFetchDevice = null;
16337faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            mFetchObjectInfo = null;
16437faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            mFetchResult = null;
165c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu        }
1660683fe0a1c913d6cc48a127bf6a1486422d1b040Bobby Georgescu        animate().cancel();
16737faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu        setImageResource(android.R.color.transparent);
16837faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu    }
169c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu
17037faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu    @Override
17137faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu    public void onDetachedFromWindow() {
17237faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu        cancelLoadingAndClear();
17337faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu        super.onDetachedFromWindow();
17437faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu    }
17537faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu
17637faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu    private static class FetchImageHandler extends Handler {
17737faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu        public FetchImageHandler(Looper l) {
17837faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            super(l);
179c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu        }
180c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu
18137faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu        public static FetchImageHandler createOnNewThread() {
18237faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            HandlerThread t = new HandlerThread("MtpImageView Fetch");
18337faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            t.start();
18437faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            return new FetchImageHandler(t.getLooper());
185c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu        }
186c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu
187c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu        @Override
18837faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu        public void handleMessage(Message msg) {
18937faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            @SuppressWarnings("unchecked")
19037faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            MtpImageView parent = ((WeakReference<MtpImageView>) msg.obj).get();
19137faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            if (parent == null) return;
19237faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            MtpObjectInfo objectInfo;
19337faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            MtpDevice device;
19437faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            synchronized (parent.mFetchLock) {
19537faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu                parent.mFetchPending = false;
19637faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu                device = parent.mFetchDevice;
19737faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu                objectInfo = parent.mFetchObjectInfo;
19837faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            }
19937faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            if (device == null) return;
20037faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            Object result = parent.fetchMtpImageDataFromDevice(device, objectInfo);
20137faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            if (result == null) return;
20237faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            synchronized (parent.mFetchLock) {
20337faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu                if (parent.mFetchObjectInfo != objectInfo) return;
20437faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu                parent.mFetchResult = result;
20537faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu                parent.mFetchDevice = null;
20637faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu                parent.mFetchObjectInfo = null;
20737faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu                sFetchCompleteHandler.sendMessage(
20837faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu                        sFetchCompleteHandler.obtainMessage(0, parent.mWeakReference));
20937faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            }
210c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu        }
211c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu    }
212c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu
21337faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu    private static class ShowImageHandler extends Handler {
21437faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu        @Override
21537faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu        public void handleMessage(Message msg) {
21637faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            @SuppressWarnings("unchecked")
21737faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            MtpImageView parent = ((WeakReference<MtpImageView>) msg.obj).get();
21837faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            if (parent == null) return;
21937faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            Object result;
22037faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            synchronized (parent.mFetchLock) {
22137faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu                result = parent.mFetchResult;
22237faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            }
22337faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            if (result == null) return;
22437faa3150feebccecd8872658af32bd88a0d2073Bobby Georgescu            parent.onMtpImageDataFetchedFromDevice(result);
225c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu        }
226c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu    }
227c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu}
228