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}