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
709c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei     * the given callback. This method will be called first; if it returns null,
719c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei     * {@link #createInputStream()} will be called.
729c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei     *
73b809a47b9f2a5dd1b6237000b525060fea21fafaMark Wei     * Clients should implement this method if files are in the local cache folder, or if files must
74b809a47b9f2a5dd1b6237000b525060fea21fafaMark Wei     * be downloaded and cached.
75b809a47b9f2a5dd1b6237000b525060fea21fafaMark Wei     *
769c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei     * This method must be called from the UI thread.
779c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei     *
789c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei     * @param key      The key to create a FileDescriptorFactory for. This key will be passed to the
799c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei     *                 callback so it can check whether the key has changed.
809c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei     * @param callback The callback to notify once the FileDescriptorFactory has been created. Do
819c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei     *                 not invoke the callback directly from this method. Instead, create a handler
829c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei     *                 and post a Runnable.
839c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei     *
849c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei     * @return If the client will attempt to create a FileDescriptorFactory, return a Cancelable
859c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei     * object to cancel the asynchronous task. If the client wants to create an InputStream instead,
869c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei     * return null. The callback must be notified if and only if the client returns a Cancelable
879c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei     * object and not null.
8840662f4b39e795d9c64502b13036e7c37fa2d373Sam Blitzstein     */
899c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei    public Cancelable createFileDescriptorFactoryAsync(RequestKey key, Callback callback);
9040662f4b39e795d9c64502b13036e7c37fa2d373Sam Blitzstein
9140662f4b39e795d9c64502b13036e7c37fa2d373Sam Blitzstein    /**
929c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei     * Create an {@link InputStream} for the source. This method will be called if
939c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei     * {@link #createFileDescriptorFactoryAsync(RequestKey, Callback)} returns null.
949c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei     *
95b809a47b9f2a5dd1b6237000b525060fea21fafaMark Wei     * Clients should implement this method if files exist in the assets/ folder, or for prototypes
96b809a47b9f2a5dd1b6237000b525060fea21fafaMark Wei     * that open a connection directly on a URL (be warned that this will cause GCs).
97b809a47b9f2a5dd1b6237000b525060fea21fafaMark Wei     *
989c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei     * This method can be called from any thread.
9940662f4b39e795d9c64502b13036e7c37fa2d373Sam Blitzstein     */
10040662f4b39e795d9c64502b13036e7c37fa2d373Sam Blitzstein    public InputStream createInputStream() throws IOException;
10140662f4b39e795d9c64502b13036e7c37fa2d373Sam Blitzstein
10240662f4b39e795d9c64502b13036e7c37fa2d373Sam Blitzstein    /**
10340662f4b39e795d9c64502b13036e7c37fa2d373Sam Blitzstein     * Return true if the image source may have be oriented in either portrait or landscape, and
10440662f4b39e795d9c64502b13036e7c37fa2d373Sam Blitzstein     * will need to be automatically re-oriented based on accompanying Exif metadata.
1059c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei     *
1069c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei     * This method can be called from any thread.
10740662f4b39e795d9c64502b13036e7c37fa2d373Sam Blitzstein     */
10840662f4b39e795d9c64502b13036e7c37fa2d373Sam Blitzstein    public boolean hasOrientationExif() throws IOException;
1099c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei
1109c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei    /**
1119c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei     * Callback for creating the {@link FileDescriptorFactory} asynchronously.
1129c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei     */
1139c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei    public interface Callback {
1149c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei
1159c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei        /**
1169c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei         * Notifies that the {@link FileDescriptorFactory} has been created. This must be called on
1179c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei         * the UI thread.
1189c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei         * @param key The key that the FileDescriptorFactory was created for. The callback should
1199c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei         *            check that the key has not changed.
1209c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei         * @param factory The FileDescriptorFactory to decode from.
1219c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei         */
1229c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei        void fileDescriptorFactoryCreated(RequestKey key, FileDescriptorFactory factory);
1239c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei    }
1249c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei
1259c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei    public interface FileDescriptorFactory {
1269c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei        ParcelFileDescriptor createFileDescriptor();
1279c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei    }
1289c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei
1299c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei    /**
1309c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei     * Interface for a background task that is cancelable.
1319c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei     */
1329c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei    public interface Cancelable {
1339c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei
1349c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei        /**
1359c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei         * Cancel the background task. This must be called on the UI thread.
1369c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei         */
1379c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei        void cancel();
1389c6ac19d4a3d39b7c2992060957920118ff56a65Mark Wei    }
13940662f4b39e795d9c64502b13036e7c37fa2d373Sam Blitzstein}