/* * Copyright (C) 2013 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.camera.app; import android.content.Context; import android.graphics.BitmapFactory; import android.location.Location; import android.net.Uri; import com.android.camera.ImageTaskManager; import com.android.camera.Storage; import com.android.camera.exif.ExifInterface; import com.android.camera.util.CameraUtil; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Iterator; public class PlaceholderManager implements ImageTaskManager { private static final String TAG = "PlaceholderManager"; public static final String PLACEHOLDER_MIME_TYPE = "application/placeholder-image"; private final Context mContext; final private ArrayList> mListenerRefs; public static class Session { String outputTitle; Uri outputUri; long time; Session(String title, Uri uri, long timestamp) { outputTitle = title; outputUri = uri; time = timestamp; } } public PlaceholderManager(Context context) { mContext = context; mListenerRefs = new ArrayList>(); } @Override public void addTaskListener(TaskListener l) { synchronized (mListenerRefs) { if (findTaskListener(l) == -1) { mListenerRefs.add(new WeakReference(l)); } } } @Override public void removeTaskListener(TaskListener l) { synchronized (mListenerRefs) { int i = findTaskListener(l); if (i != -1) { mListenerRefs.remove(i); } } } @Override public int getTaskProgress(Uri uri) { return 0; } private int findTaskListener(TaskListener listener) { int index = -1; for (int i = 0; i < mListenerRefs.size(); i++) { TaskListener l = mListenerRefs.get(i).get(); if (l != null && l == listener) { index = i; break; } } return index; } private Iterable getListeners() { return new Iterable() { @Override public Iterator iterator() { return new ListenerIterator(); } }; } private class ListenerIterator implements Iterator { private int mIndex = 0; private TaskListener mNext = null; @Override public boolean hasNext() { while (mNext == null && mIndex < mListenerRefs.size()) { mNext = mListenerRefs.get(mIndex).get(); if (mNext == null) { mListenerRefs.remove(mIndex); } } return mNext != null; } @Override public TaskListener next() { hasNext(); // Populates mNext mIndex++; TaskListener next = mNext; mNext = null; return next; } @Override public void remove() { throw new UnsupportedOperationException(); } } public Session insertPlaceholder(String title, byte[] placeholder, long timestamp) { if (title == null || placeholder == null) { throw new IllegalArgumentException("Null argument passed to insertPlaceholder"); } // Decode bounds BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeByteArray(placeholder, 0, placeholder.length, options); int width = options.outWidth; int height = options.outHeight; if (width <= 0 || height <= 0) { throw new IllegalArgumentException("Image had bad height/width"); } Uri uri = Storage.addImage(mContext.getContentResolver(), title, timestamp, null, 0, null, placeholder, width, height, PLACEHOLDER_MIME_TYPE); if (uri == null) { return null; } String filePath = uri.getPath(); synchronized (mListenerRefs) { for (TaskListener l : getListeners()) { l.onTaskQueued(filePath, uri); } } return new Session(title, uri, timestamp); } public void replacePlaceholder(Session session, Location location, int orientation, ExifInterface exif, byte[] jpeg, int width, int height, String mimeType) { Storage.updateImage(session.outputUri, mContext.getContentResolver(), session.outputTitle, session.time, location, orientation, exif, jpeg, width, height, mimeType); synchronized (mListenerRefs) { for (TaskListener l : getListeners()) { l.onTaskDone(session.outputUri.getPath(), session.outputUri); } } CameraUtil.broadcastNewPicture(mContext, session.outputUri); } public void removePlaceholder(Session session) { Storage.deleteImage(mContext.getContentResolver(), session.outputUri); } }