140662f4b39e795d9c64502b13036e7c37fa2d373Sam Blitzstein/*
240662f4b39e795d9c64502b13036e7c37fa2d373Sam Blitzstein * Copyright (C) 2013 The Android Open Source Project
340662f4b39e795d9c64502b13036e7c37fa2d373Sam Blitzstein *
440662f4b39e795d9c64502b13036e7c37fa2d373Sam Blitzstein * Licensed under the Apache License, Version 2.0 (the "License");
540662f4b39e795d9c64502b13036e7c37fa2d373Sam Blitzstein * you may not use this file except in compliance with the License.
640662f4b39e795d9c64502b13036e7c37fa2d373Sam Blitzstein * You may obtain a copy of the License at
740662f4b39e795d9c64502b13036e7c37fa2d373Sam Blitzstein *
840662f4b39e795d9c64502b13036e7c37fa2d373Sam Blitzstein *      http://www.apache.org/licenses/LICENSE-2.0
940662f4b39e795d9c64502b13036e7c37fa2d373Sam Blitzstein *
1040662f4b39e795d9c64502b13036e7c37fa2d373Sam Blitzstein * Unless required by applicable law or agreed to in writing, software
1140662f4b39e795d9c64502b13036e7c37fa2d373Sam Blitzstein * distributed under the License is distributed on an "AS IS" BASIS,
1240662f4b39e795d9c64502b13036e7c37fa2d373Sam Blitzstein * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1340662f4b39e795d9c64502b13036e7c37fa2d373Sam Blitzstein * See the License for the specific language governing permissions and
1440662f4b39e795d9c64502b13036e7c37fa2d373Sam Blitzstein * limitations under the License.
1540662f4b39e795d9c64502b13036e7c37fa2d373Sam Blitzstein */
1640662f4b39e795d9c64502b13036e7c37fa2d373Sam Blitzstein
1740662f4b39e795d9c64502b13036e7c37fa2d373Sam Blitzsteinpackage com.android.bitmap;
1840662f4b39e795d9c64502b13036e7c37fa2d373Sam Blitzstein
19cea0c012d538f11b3ee97d4b7e78f4c1ea73d5beMark Weiimport android.os.ParcelFileDescriptor;
2040662f4b39e795d9c64502b13036e7c37fa2d373Sam Blitzstein
2140662f4b39e795d9c64502b13036e7c37fa2d373Sam Blitzsteinimport java.io.IOException;
2240662f4b39e795d9c64502b13036e7c37fa2d373Sam Blitzsteinimport java.io.InputStream;
2340662f4b39e795d9c64502b13036e7c37fa2d373Sam Blitzstein
2440662f4b39e795d9c64502b13036e7c37fa2d373Sam Blitzstein/**
2540662f4b39e795d9c64502b13036e7c37fa2d373Sam Blitzstein * The decode task uses this class to get input to decode. You must implement at least one of
269c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei * {@link #createFileDescriptorFactoryAsync(RequestKey, Callback)} or {@link #createInputStream()}.
279c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei * {@link DecodeTask} will prioritize
289c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei * {@link #createFileDescriptorFactoryAsync(RequestKey, Callback)} before falling back to
299c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei * {@link #createInputStream()}.
309c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei *
3125ad6f98516a7af1ca71cfa07fb503d46dc8a7f1Sam Blitzstein * <p>
3225ad6f98516a7af1ca71cfa07fb503d46dc8a7f1Sam Blitzstein * Clients of this interface must also implement {@link #equals(Object)} and {@link #hashCode()} as
3325ad6f98516a7af1ca71cfa07fb503d46dc8a7f1Sam Blitzstein * this object will be used as a cache key.
349c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei *
359c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei * <p>
369c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei * The following is a high level view of the interactions between RequestKey and the rest of the
379c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei * system.
389c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei *
399c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei *       BasicBitmapDrawable
409c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei *           UI Thread
419c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei *              ++
429c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei *       bind() ||            Background Thread
439c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei *              |+-------------------->+
449c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei *              || createFDFasync()   ||
459c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei *              ||                    || Download from url
469c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei *              ||                    || Cache on disk
479c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei *              ||                    ||
489c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei *              ||                    vv
499c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei *              |<--------------------+x
509c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei *              ||        FDFcreated()
519c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei *              ||
529c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei *              ||
539c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei *              ||                DecodeTask
549c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei *              ||             AsyncTask Thread
559c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei *              |+-------------------->+
569c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei *              || new().execute()    ||
579c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei *              ||                    || Decode from FDF
589c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei *              ||                    || or createInputStream()
599c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei *              ||                    ||
609c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei *              ||                    vv
619c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei *              |<--------------------+x
629c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei *              ||  onDecodeComplete()
639c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei *              vv
649c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei * invalidate() xx
6540662f4b39e795d9c64502b13036e7c37fa2d373Sam Blitzstein */
6640662f4b39e795d9c64502b13036e7c37fa2d373Sam Blitzsteinpublic interface RequestKey {
679c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei
6840662f4b39e795d9c64502b13036e7c37fa2d373Sam Blitzstein    /**
699c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei     * Create an {@link FileDescriptorFactory} for a local file stored on the device and pass it to
70a8b1e1f5cad36086e89c052007473609c379ccbdOleksandr Kyreiev     * the given callback. This method will be called in favor of {@link #createInputStream()}},
71a8b1e1f5cad36086e89c052007473609c379ccbdOleksandr Kyreiev     * which will only be called if null is returned from this method,
72a8b1e1f5cad36086e89c052007473609c379ccbdOleksandr Kyreiev     * or {@link Callback#fileDescriptorFactoryCreated(RequestKey, FileDescriptorFactory)} is called
73a8b1e1f5cad36086e89c052007473609c379ccbdOleksandr Kyreiev     * with a null FileDescriptorFactory.
749c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei     *
75b809a47b9f2a5dd1b6237000b525060fea21fafaMark Wei     * Clients should implement this method if files are in the local cache folder, or if files must
76b809a47b9f2a5dd1b6237000b525060fea21fafaMark Wei     * be downloaded and cached.
77b809a47b9f2a5dd1b6237000b525060fea21fafaMark Wei     *
789c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei     * This method must be called from the UI thread.
799c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei     *
809c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei     * @param key      The key to create a FileDescriptorFactory for. This key will be passed to the
819c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei     *                 callback so it can check whether the key has changed.
82a8b1e1f5cad36086e89c052007473609c379ccbdOleksandr Kyreiev     * @param callback The callback to notify once the FileDescriptorFactory is created or has failed
83a8b1e1f5cad36086e89c052007473609c379ccbdOleksandr Kyreiev     *                 to be created.
84a8b1e1f5cad36086e89c052007473609c379ccbdOleksandr Kyreiev     *                 Do not invoke the callback directly from this method. Instead, create a handler
859c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei     *                 and post a Runnable.
869c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei     *
879c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei     * @return If the client will attempt to create a FileDescriptorFactory, return a Cancelable
889c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei     * object to cancel the asynchronous task. If the client wants to create an InputStream instead,
899c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei     * return null. The callback must be notified if and only if the client returns a Cancelable
909c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei     * object and not null.
9140662f4b39e795d9c64502b13036e7c37fa2d373Sam Blitzstein     */
929c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei    public Cancelable createFileDescriptorFactoryAsync(RequestKey key, Callback callback);
9340662f4b39e795d9c64502b13036e7c37fa2d373Sam Blitzstein
9440662f4b39e795d9c64502b13036e7c37fa2d373Sam Blitzstein    /**
959c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei     * Create an {@link InputStream} for the source. This method will be called if
969c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei     * {@link #createFileDescriptorFactoryAsync(RequestKey, Callback)} returns null.
979c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei     *
98b809a47b9f2a5dd1b6237000b525060fea21fafaMark Wei     * Clients should implement this method if files exist in the assets/ folder, or for prototypes
99b809a47b9f2a5dd1b6237000b525060fea21fafaMark Wei     * that open a connection directly on a URL (be warned that this will cause GCs).
100b809a47b9f2a5dd1b6237000b525060fea21fafaMark Wei     *
1019c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei     * This method can be called from any thread.
10240662f4b39e795d9c64502b13036e7c37fa2d373Sam Blitzstein     */
10340662f4b39e795d9c64502b13036e7c37fa2d373Sam Blitzstein    public InputStream createInputStream() throws IOException;
10440662f4b39e795d9c64502b13036e7c37fa2d373Sam Blitzstein
10540662f4b39e795d9c64502b13036e7c37fa2d373Sam Blitzstein    /**
10640662f4b39e795d9c64502b13036e7c37fa2d373Sam Blitzstein     * Return true if the image source may have be oriented in either portrait or landscape, and
10740662f4b39e795d9c64502b13036e7c37fa2d373Sam Blitzstein     * will need to be automatically re-oriented based on accompanying Exif metadata.
1089c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei     *
1099c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei     * This method can be called from any thread.
11040662f4b39e795d9c64502b13036e7c37fa2d373Sam Blitzstein     */
11140662f4b39e795d9c64502b13036e7c37fa2d373Sam Blitzstein    public boolean hasOrientationExif() throws IOException;
1129c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei
1139c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei    /**
1149c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei     * Callback for creating the {@link FileDescriptorFactory} asynchronously.
1159c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei     */
1169c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei    public interface Callback {
1179c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei
1189c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei        /**
1199c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei         * Notifies that the {@link FileDescriptorFactory} has been created. This must be called on
1209c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei         * the UI thread.
1219c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei         * @param key The key that the FileDescriptorFactory was created for. The callback should
1229c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei         *            check that the key has not changed.
123c5644927c0e7e121049b063046296ee8a59a4b37Mark Wei         * @param factory The FileDescriptorFactory to decode from. Pass null to cancel decode.
1249c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei         */
1259c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei        void fileDescriptorFactoryCreated(RequestKey key, FileDescriptorFactory factory);
1269c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei    }
1279c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei
1289c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei    public interface FileDescriptorFactory {
1299c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei        ParcelFileDescriptor createFileDescriptor();
1309c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei    }
1319c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei
1329c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei    /**
1339c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei     * Interface for a background task that is cancelable.
1349c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei     */
1359c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei    public interface Cancelable {
1369c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei
1379c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei        /**
1389c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei         * Cancel the background task. This must be called on the UI thread.
1399c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei         */
1409c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei        void cancel();
1419c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei    }
142a8b1e1f5cad36086e89c052007473609c379ccbdOleksandr Kyreiev}
143