Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 962f9f02 authored by Angus Kong's avatar Angus Kong
Browse files

Add LocalDataAdapter and wrappers.

1. FixedFirstDataAdapter wraps another adapter and add a data at the first
position.
2. FixedLastDataAdapter wraps another adapter and add a data at the last
position.
3. Make the LocalData interface more complete.
  - onFullScreen()
  - canSwipeInFullScreen()
  - getPath()
3. Add methods to the FilmStripView.DataAdapter to receive UI events.
  - onDataCentered()
  - onDataFullScreen()

Change-Id: I26d3a3b7facd0c451af43ce5fbbcab2baaaec427
parent 7c547a76
Loading
Loading
Loading
Loading
+25 −11
Original line number Diff line number Diff line
@@ -42,7 +42,11 @@ import android.view.WindowManager;
import android.widget.ImageView;

import com.android.camera.data.CameraDataAdapter;
import com.android.camera.data.CameraPreviewData;
import com.android.camera.data.FixedFirstDataAdapter;
import com.android.camera.data.FixedLastDataAdapter;
import com.android.camera.data.LocalData;
import com.android.camera.data.LocalDataAdapter;
import com.android.camera.ui.CameraSwitcher;
import com.android.camera.ui.CameraSwitcher.CameraSwitchListener;
import com.android.camera.ui.FilmStripView;
@@ -68,7 +72,11 @@ public class CameraActivity extends Activity
    // panorama. If the extra is not set, it is in the normal camera mode.
    public static final String SECURE_CAMERA_EXTRA = "secure_camera";

    private CameraDataAdapter mDataAdapter;
    /** This data adapter is used by FilmStirpView. */
    private LocalDataAdapter mDataAdapter;
    /** This data adapter represents the real local camera data. */
    private LocalDataAdapter mWrappedDataAdapter;

    private PanoramaStitchingManager mPanoramaManager;
    private int mCurrentModuleIndex;
    private CameraModule mCurrentModule;
@@ -87,6 +95,7 @@ public class CameraActivity extends Activity
    private MyOrientationEventListener mOrientationListener;
    private Handler mMainHandler;
    private PanoramaViewHelper mPanoramaViewHelper;
    private CameraPreviewData mCameraPreviewData;

    private class MyOrientationEventListener
        extends OrientationEventListener {
@@ -267,8 +276,13 @@ public class CameraActivity extends Activity
        LayoutInflater inflater = getLayoutInflater();
        View rootLayout = inflater.inflate(R.layout.camera, null, false);
        mRootView = rootLayout.findViewById(R.id.camera_app_root);
        mDataAdapter = new CameraDataAdapter(
                new ColorDrawable(getResources().getColor(R.color.photo_placeholder)));
        mCameraPreviewData = new CameraPreviewData(rootLayout,
                FilmStripView.ImageData.SIZE_FULL,
                FilmStripView.ImageData.SIZE_FULL);
        mWrappedDataAdapter = new FixedFirstDataAdapter(
                new CameraDataAdapter(new ColorDrawable(
                        getResources().getColor(R.color.photo_placeholder))),
                mCameraPreviewData);
        mFilmStripView = (FilmStripView) findViewById(R.id.filmstrip_view);
        mFilmStripView.setViewGap(
                getResources().getDimensionPixelSize(R.dimen.camera_film_strip_gap));
@@ -276,9 +290,6 @@ public class CameraActivity extends Activity
        mPanoramaViewHelper.onCreate();
        mFilmStripView.setPanoramaViewHelper(mPanoramaViewHelper);
        // Set up the camera preview first so the preview shows up ASAP.
        mDataAdapter.setCameraPreviewInfo(rootLayout,
                FilmStripView.ImageData.SIZE_FULL, FilmStripView.ImageData.SIZE_FULL);
        mFilmStripView.setDataAdapter(mDataAdapter);
        mFilmStripView.setListener(mFilmStripListener);
        mCurrentModule = new PhotoModule();
        mCurrentModule.init(this, mRootView);
@@ -334,19 +345,22 @@ public class CameraActivity extends Activity

        // The loading is done in background and will update the filmstrip later.
        if (!mSecureCamera) {
            mDataAdapter = mWrappedDataAdapter;
            mDataAdapter.requestLoad(getContentResolver());
            mFilmStripView.setDataAdapter(mDataAdapter);
        } else {
            // Flush out all the original data first.
            mDataAdapter.flush();
            // Put a lock placeholder as the last image by setting its date to 0.
            ImageView v = (ImageView) getLayoutInflater().inflate(
                    R.layout.secure_album_placeholder, null);
            // Put a lock placeholder as the last image by setting its date to 0.
            mDataAdapter.addLocalData(
            mDataAdapter = new FixedLastDataAdapter(
                    mWrappedDataAdapter,
                    new LocalData.LocalViewData(
                            v,
                            v.getDrawable().getIntrinsicWidth(),
                            v.getDrawable().getIntrinsicHeight(),
                            0, 0));
            // Flush out all the original data.
            mDataAdapter.flush();
        }
        mPanoramaViewHelper.onStart();
    }
@@ -515,7 +529,7 @@ public class CameraActivity extends Activity
    }

    public void setSwipingEnabled(boolean enable) {
        mDataAdapter.setCameraPreviewLock(!enable);
        mCameraPreviewData.lockPreview(!enable);
    }

    // Accessor methods for getting latency times used in performance testing
+1 −1
Original line number Diff line number Diff line
@@ -342,7 +342,7 @@ public class PhotoUI implements PieListener,

    public void initializeControlByIntent() {
        mBlocker = mRootView.findViewById(R.id.blocker);
        mPreviewThumb = mActivity.findViewById(R.id.preview_thumb);
        mPreviewThumb = mRootView.findViewById(R.id.preview_thumb);
        mPreviewThumb.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
+90 −0
Original line number Diff line number Diff line
/*
 * 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.data;

import android.content.ContentResolver;
import android.content.Context;
import android.net.Uri;

/**
 * An abstract {@link LocalDataAdapter} implementation to wrap another
 * {@link LocalDataAdapter}. All implementations related to data id is not
 * addressed in this abstract class since wrapping another data adapter
 * surely makes things different for data id.
 *
 * @see FixedFirstDataAdapter
 * @see FixedLastDataAdapter
 */
public abstract class AbstractLocalDataAdapterWrapper implements LocalDataAdapter {

    protected final LocalDataAdapter mAdapter;
    protected int mSuggestedWidth;
    protected int mSuggestedHeight;

    /**
     * Constructor.
     *
     * @param wrappedAdapter  The {@link LocalDataAdapter} to be wrapped.
     */
    AbstractLocalDataAdapterWrapper(LocalDataAdapter wrappedAdapter) {
        if (wrappedAdapter == null) {
            throw new AssertionError("data adapter is null");
        }
        mAdapter = wrappedAdapter;
    }

    @Override
    public void suggestViewSizeBound(int w, int h) {
        mSuggestedWidth = w;
        mSuggestedHeight = h;
    }

    @Override
    public void setListener(Listener listener) {
        mAdapter.setListener(listener);
    }

    @Override
    public void requestLoad(ContentResolver resolver) {
        mAdapter.requestLoad(resolver);
    }

    @Override
    public void addNewVideo(ContentResolver resolver, Uri uri) {
        mAdapter.addNewVideo(resolver, uri);
    }

    @Override
    public void addNewPhoto(ContentResolver resolver, Uri uri) {
        mAdapter.addNewPhoto(resolver, uri);
    }

    @Override
    public void flush() {
        mAdapter.flush();
    }

    @Override
    public boolean executeDeletion(Context context) {
        return mAdapter.executeDeletion(context);
    }

    @Override
    public boolean undoDataRemoval() {
        return mAdapter.undoDataRemoval();
    }
}
+43 −168
Original line number Diff line number Diff line
@@ -27,7 +27,6 @@ import android.util.Log;
import android.view.View;

import com.android.camera.Storage;
import com.android.camera.ui.FilmStripView;
import com.android.camera.ui.FilmStripView.ImageData;
import com.android.gallery3d.util.LightCycleHelper.PanoramaViewHelper;

@@ -37,12 +36,9 @@ import java.util.Comparator;
import java.util.List;

/**
 * A FilmStrip.DataProvider that provide data in the camera folder.
 *
 * The given view for camera preview won't be added until the preview info
 * has been set by setCameraPreviewInfo(int, int).
 * A {@link LocalDataAdapter} that provides data in the camera folder.
 */
public class CameraDataAdapter implements FilmStripView.DataAdapter {
public class CameraDataAdapter implements LocalDataAdapter {
    private static final String TAG = CameraDataAdapter.class.getSimpleName();

    private static final int DEFAULT_DECODE_SIZE = 3000;
@@ -51,33 +47,23 @@ public class CameraDataAdapter implements FilmStripView.DataAdapter {
    private List<LocalData> mImages;

    private Listener mListener;
    private View mCameraPreviewView;
    private Drawable mPlaceHolder;

    private int mSuggestedWidth = DEFAULT_DECODE_SIZE;
    private int mSuggestedHeight = DEFAULT_DECODE_SIZE;

    private boolean mCameraPreviewLocked;
    private LocalData mLocalDataToDelete;

    public CameraDataAdapter(Drawable placeHolder) {
        mPlaceHolder = placeHolder;
    }

    public void setCameraPreviewInfo(View cameraPreview, int width, int height) {
        mCameraPreviewView = cameraPreview;
        addOrReplaceCameraData(buildCameraImageData(width, height));
    }

    @Override
    public void requestLoad(ContentResolver resolver) {
        QueryTask qtask = new QueryTask();
        qtask.execute(resolver);
    }

    public void setCameraPreviewLock(boolean locked) {
        mCameraPreviewLocked = locked;
    }

    @Override
    public int getTotalNumber() {
        if (mImages == null) {
@@ -91,15 +77,8 @@ public class CameraDataAdapter implements FilmStripView.DataAdapter {
        return getData(id);
    }

    public LocalData getData(int id) {
        if (mImages == null || id >= mImages.size() || id < 0) {
            return null;
        }
        return mImages.get(id);
    }

    @Override
    public void suggestDecodeSize(int w, int h) {
    public void suggestViewSizeBound(int w, int h) {
        if (w <= 0 || h <= 0) {
            mSuggestedWidth  = mSuggestedHeight = DEFAULT_DECODE_SIZE;
        } else {
@@ -131,14 +110,26 @@ public class CameraDataAdapter implements FilmStripView.DataAdapter {
    }

    @Override
    public boolean canSwipeInFullScreen(int id) {
        if (mImages.get(id).getType()
                == ImageData.TYPE_CAMERA_PREVIEW) {
            return !mCameraPreviewLocked;
    public void onDataFullScreen(int dataID, boolean fullScreen) {
        if (dataID < mImages.size() && dataID >= 0) {
            mImages.get(dataID).onFullScreen(fullScreen);
        }
        return false;
    }

    @Override
    public void onDataCentered(int dataID, boolean centered) {
        // do nothing.
    }

    @Override
    public boolean canSwipeInFullScreen(int dataID) {
        if (dataID < mImages.size() && dataID > 0) {
            return mImages.get(dataID).canSwipeInFullScreen();
        }
        return true;
    }

    @Override
    public void removeData(Context c, int dataID) {
        if (dataID >= mImages.size()) return;
        LocalData d = mImages.remove(dataID);
@@ -166,6 +157,7 @@ public class CameraDataAdapter implements FilmStripView.DataAdapter {
        }
    }

    @Override
    public void addNewVideo(ContentResolver cr, Uri uri) {
        Cursor c = cr.query(uri,
                LocalData.Video.QUERY_PROJECTION,
@@ -176,6 +168,7 @@ public class CameraDataAdapter implements FilmStripView.DataAdapter {
        }
    }

    @Override
    public void addNewPhoto(ContentResolver cr, Uri uri) {
        Cursor c = cr.query(uri,
                LocalData.Photo.QUERY_PROJECTION,
@@ -186,6 +179,13 @@ public class CameraDataAdapter implements FilmStripView.DataAdapter {
        }
    }

    @Override
    public int findDataByContentUri(Uri uri) {
        // TODO: find the data.
        return -1;
    }

    @Override
    public boolean undoDataRemoval() {
        if (mLocalDataToDelete == null) return false;
        LocalData d = mLocalDataToDelete;
@@ -194,6 +194,7 @@ public class CameraDataAdapter implements FilmStripView.DataAdapter {
        return true;
    }

    @Override
    public boolean executeDeletion(Context c) {
        if (mLocalDataToDelete == null) return false;

@@ -203,6 +204,18 @@ public class CameraDataAdapter implements FilmStripView.DataAdapter {
        return true;
    }

    @Override
    public void flush() {
        replaceData(null);
    }

    private LocalData getData(int id) {
        if (mImages == null || id >= mImages.size() || id < 0) {
            return null;
        }
        return mImages.get(id);
    }

    // Update all the data but keep the camera data if already set.
    private void replaceData(List<LocalData> list) {
        boolean changed = (list != mImages);
@@ -244,61 +257,6 @@ public class CameraDataAdapter implements FilmStripView.DataAdapter {
        }
    }

    public void flush() {
        replaceData(null);
    }

    public void addLocalData(LocalData data) {
        insertData(data);
    }

    private LocalData buildCameraImageData(int width, int height) {
        LocalData d = new CameraPreviewData(width, height);
        return d;
    }

    private void addOrReplaceCameraData(LocalData data) {
        if (mImages == null) {
            mImages = new ArrayList<LocalData>();
        }
        if (mImages.size() == 0) {
            // No data at all.
            mImages.add(0, data);
            if (mListener != null) {
                mListener.onDataLoaded();
            }
            return;
        }

        LocalData first = mImages.get(0);
        if (first.getType() == ImageData.TYPE_CAMERA_PREVIEW) {
            // Replace the old camera data.
            mImages.set(0, data);
            if (mListener != null) {
                mListener.onDataUpdated(new UpdateReporter() {
                    @Override
                    public boolean isDataRemoved(int id) {
                        return false;
                    }

                    @Override
                    public boolean isDataUpdated(int id) {
                        if (id == 0) {
                            return true;
                        }
                        return false;
                    }
                });
            }
        } else {
            // Add a new camera data.
            mImages.add(0, data);
            if (mListener != null) {
                mListener.onDataLoaded();
            }
        }
    }

    private class QueryTask extends AsyncTask<ContentResolver, Void, List<LocalData>> {
        @Override
        protected List<LocalData> doInBackground(ContentResolver... resolver) {
@@ -387,87 +345,4 @@ public class CameraDataAdapter implements FilmStripView.DataAdapter {
            return null;
        }
    }

    private class CameraPreviewData implements LocalData {
        private int width;
        private int height;

        CameraPreviewData(int w, int h) {
            width = w;
            height = h;
        }

        @Override
        public long getDateTaken() {
            // This value is used for sorting.
            return -1;
        }

        @Override
        public long getDateModified() {
            // This value might be used for sorting.
            return -1;
        }

        @Override
        public String getTitle() {
            return "";
        }

        @Override
        public int getWidth() {
            return width;
        }

        @Override
        public int getHeight() {
            return height;
        }

        @Override
        public int getType() {
            return ImageData.TYPE_CAMERA_PREVIEW;
        }

        @Override
        public boolean isUIActionSupported(int action) {
            return false;
        }

        @Override
        public boolean isDataActionSupported(int action) {
            return false;
        }

        @Override
        public boolean delete(Context c) {
            return false;
        }

        @Override
        public View getView(Context c, int width, int height, Drawable placeHolder) {
            return mCameraPreviewView;
        }

        @Override
        public void prepare() {
            // do nothing.
        }

        @Override
        public void recycle() {
            // do nothing.
        }

        @Override
        public void isPhotoSphere(Context context, PanoramaSupportCallback callback) {
            // Not a photo sphere panorama.
            callback.panoramaInfoAvailable(false, false);
        }

        @Override
        public void viewPhotoSphere(PanoramaViewHelper helper) {
            // do nothing.
        }
    }
}
+63 −0
Original line number Diff line number Diff line
/*
 * 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.data;

import android.view.View;

import com.android.camera.ui.FilmStripView.ImageData;

/**
 * A class implementing {@link LocalData} to represent a camera preview.
 */
public class CameraPreviewData extends LocalData.LocalViewData {

    private boolean mPreviewLocked;

    /**
     * Constructor.
     *
     * @param v      The {@link android.view.View} for camera preview.
     * @param width  The width of the camera preview.
     * @param height The height of the camera preview.
     */
    public CameraPreviewData(View v, int width, int height) {
        super(v, width, height, -1, -1);
        mPreviewLocked = true;
    }

    @Override
    public int getType() {
        return ImageData.TYPE_CAMERA_PREVIEW;
    }

    @Override
    public boolean canSwipeInFullScreen() {
        return !mPreviewLocked;
    }

    /**
     * Locks the camera preview. When the camera preview is locked, swipe
     * to film strip is not allowed. One case is when the video recording
     * is in progress.
     *
     * @param lock {@code true} if the preview should be locked. {@code false}
     *             otherwise.
     */
    public void lockPreview(boolean lock) {
        mPreviewLocked = lock;
    }
}
Loading