blob: 7403c7f82e12551a57304db147b77937ec9b6e69 [file] [log] [blame]
Sascha Haeberlinga63dbb62013-11-22 11:55:32 -08001/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.camera.session;
18
19import android.content.ContentResolver;
20import android.content.Context;
21import android.database.Cursor;
22import android.graphics.BitmapFactory;
23import android.location.Location;
24import android.net.Uri;
25import android.provider.MediaStore;
26
27import com.android.camera.Storage;
Angus Kong2bca2102014-03-11 16:27:30 -070028import com.android.camera.debug.Log;
Sascha Haeberlinga63dbb62013-11-22 11:55:32 -080029import com.android.camera.exif.ExifInterface;
30import com.android.camera.util.CameraUtil;
31
32/**
33 * Handles placeholders in filmstrip that show up temporarily while a final
34 * output media item is being produced.
35 */
36public class PlaceholderManager {
Angus Kong2bca2102014-03-11 16:27:30 -070037 private static final Log.Tag TAG = new Log.Tag("PlaceholderMgr");
Sascha Haeberlinga63dbb62013-11-22 11:55:32 -080038
Sascha Haeberlinga63dbb62013-11-22 11:55:32 -080039 private final Context mContext;
40
41 public static class Session {
42 final String outputTitle;
43 final Uri outputUri;
44 final long time;
45
46 Session(String title, Uri uri, long timestamp) {
47 outputTitle = title;
48 outputUri = uri;
49 time = timestamp;
50 }
51 }
52
53 public PlaceholderManager(Context context) {
54 mContext = context;
55 }
56
57 public Session insertPlaceholder(String title, byte[] placeholder, long timestamp) {
58 if (title == null || placeholder == null) {
59 throw new IllegalArgumentException("Null argument passed to insertPlaceholder");
60 }
61
62 // Decode bounds
63 BitmapFactory.Options options = new BitmapFactory.Options();
64 options.inJustDecodeBounds = true;
65 BitmapFactory.decodeByteArray(placeholder, 0, placeholder.length, options);
66 int width = options.outWidth;
67 int height = options.outHeight;
68
69 if (width <= 0 || height <= 0) {
70 throw new IllegalArgumentException("Image had bad height/width");
71 }
72
73 Uri uri =
Seth Raphael455ba5a2014-02-13 15:10:06 -080074 Storage.addPlaceholder(placeholder, width, height);
Sascha Haeberlinga63dbb62013-11-22 11:55:32 -080075 if (uri == null) {
76 return null;
77 }
78 return new Session(title, uri, timestamp);
79 }
80
81 /**
82 * Converts an existing item into a placeholder for re-processing.
83 *
84 * @param uri the URI of an existing media item.
85 * @return A session that can be used to update the progress of the new
86 * session.
87 */
88 public Session convertToPlaceholder(Uri uri) {
Sascha Haeberlinga63dbb62013-11-22 11:55:32 -080089 return createSessionFromUri(uri);
90 }
91
Sascha Haeberlinga63dbb62013-11-22 11:55:32 -080092 /**
Seth Raphael455ba5a2014-02-13 15:10:06 -080093 * This converts the placeholder in to a real media item
Sascha Haeberling14ff6c82013-12-13 13:29:58 -080094 *
Seth Raphael455ba5a2014-02-13 15:10:06 -080095 * @param session the session that is being finished.
96 * @param location the location of the image
97 * @param orientation the orientation of the image
98 * @param exif the exif of the image
99 * @param jpeg the bytes of the image
100 * @param width the width of the image
101 * @param height the height of the image
102 * @param mimeType the mime type of the image
Seth Raphael93c6b612014-03-13 11:01:26 -0700103 * @return The content URI of the new media item.
Sascha Haeberlinga63dbb62013-11-22 11:55:32 -0800104 */
Seth Raphael93c6b612014-03-13 11:01:26 -0700105 public Uri finishPlaceholder(Session session, Location location, int orientation,
106 ExifInterface exif, byte[] jpeg, int width, int height, String mimeType) {
Seth Raphael455ba5a2014-02-13 15:10:06 -0800107
108 Uri resultUri = Storage.updateImage(session.outputUri, mContext.getContentResolver(), session.outputTitle,
109 session.time, location, orientation, exif, jpeg, width, height, mimeType);
110 CameraUtil.broadcastNewPicture(mContext, resultUri);
Seth Raphael93c6b612014-03-13 11:01:26 -0700111 return resultUri;
Sascha Haeberlinga63dbb62013-11-22 11:55:32 -0800112 }
113
114 /**
Seth Raphael455ba5a2014-02-13 15:10:06 -0800115 * This changes the temporary placeholder jpeg without writing it to the media store
116 *
117 * @param session the session to update
118 * @param jpeg the new placeholder bytes
119 * @param width the width of the image
120 * @param height the height of the image
Sascha Haeberlinga63dbb62013-11-22 11:55:32 -0800121 */
Seth Raphael455ba5a2014-02-13 15:10:06 -0800122 public void replacePlaceholder(Session session,
123 byte[] jpeg, int width, int height) {
124
125 Storage.replacePlaceholder(session.outputUri,
126 jpeg, width, height);
127 CameraUtil.broadcastNewPicture(mContext, session.outputUri);
Sascha Haeberlinga63dbb62013-11-22 11:55:32 -0800128 }
129
130 /**
131 * Create a new session instance from the given URI by querying the media
132 * store.
133 * <p>
134 * TODO: Make sure this works with types other than images when needed.
135 */
136 private Session createSessionFromUri(Uri uri) {
137 ContentResolver resolver = mContext.getContentResolver();
138
139 Cursor cursor = resolver.query(uri,
140 new String[] {
141 MediaStore.Images.Media.DATE_TAKEN, MediaStore.Images.Media.DISPLAY_NAME,
142 }, null, null, null);
143 if (cursor == null) {
144 return null;
145 }
146 int dateIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATE_TAKEN);
147 int nameIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DISPLAY_NAME);
148
149 cursor.moveToFirst();
150 long date = cursor.getLong(dateIndex);
151 String name = cursor.getString(nameIndex);
152
153 if (name.toLowerCase().endsWith(Storage.JPEG_POSTFIX)) {
154 name = name.substring(0, name.length() - Storage.JPEG_POSTFIX.length());
155 }
156
157 return new Session(name, uri, date);
158 }
159}