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

Commit 45e666c6 authored by nicolasroard's avatar nicolasroard Committed by Android (Google) Code Review
Browse files

Merge "Implements image sharing" into gb-ub-photos-arches

parents 9481d05b 0ee91a2b
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -225,6 +225,18 @@
            </intent-filter>
        </activity>

        <permission android:name="com.android.gallery3d.filtershow.permission.READ"
                    android:protectionLevel="signature" />

        <permission android:name="com.android.gallery3d.filtershow.permission.WRITE"
                    android:protectionLevel="signature" />

        <provider
            android:name="com.android.gallery3d.filtershow.provider.SharedImageProvider"
            android:authorities="com.android.gallery3d.filtershow.provider.SharedImageProvider"
            android:grantUriPermissions="true"
            android:readPermission="com.android.gallery3d.filtershow.permission.READ"
            android:writePermission="com.android.gallery3d.filtershow.permission.WRITE" />
        <activity
            android:name="com.android.gallery3d.filtershow.FilterShowActivity"
            android:label="@string/title_activity_filter_show"
+59 −8
Original line number Diff line number Diff line

package com.android.gallery3d.filtershow;

import java.io.File;
import java.io.IOException;
import java.util.Vector;

import com.android.gallery3d.filtershow.cache.ImageLoader;
@@ -10,6 +12,8 @@ import com.android.gallery3d.filtershow.imageshow.ImageShow;
import com.android.gallery3d.filtershow.imageshow.ImageSmallFilter;
import com.android.gallery3d.filtershow.imageshow.ImageStraighten;
import com.android.gallery3d.filtershow.presets.*;
import com.android.gallery3d.filtershow.provider.SharedImageProvider;
import com.android.gallery3d.filtershow.tools.SaveCopyTask;
import com.android.gallery3d.filtershow.ui.ImageCurves;
import com.android.gallery3d.R;

@@ -18,6 +22,7 @@ import android.os.Bundle;
import android.annotation.TargetApi;
import android.app.ActionBar;
import android.app.Activity;
import android.content.ContentValues;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
@@ -31,7 +36,6 @@ import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.widget.AbsoluteLayout;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
@@ -40,10 +44,13 @@ import android.widget.FrameLayout.LayoutParams;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ShareActionProvider;
import android.widget.ShareActionProvider.OnShareTargetSelectedListener;
import android.widget.Toast;

@TargetApi(16)
public class FilterShowActivity extends Activity implements OnItemClickListener {
public class FilterShowActivity extends Activity implements OnItemClickListener,
        OnShareTargetSelectedListener {

    private ImageLoader mImageLoader = null;
    private ImageShow mImageShow = null;
@@ -84,6 +91,11 @@ public class FilterShowActivity extends Activity implements OnItemClickListener
    private Vector<ImageButton> mBottomPanelButtons = new Vector<ImageButton>();
    private Vector<ImageButton> mColorsPanelButtons = new Vector<ImageButton>();

    private ShareActionProvider mShareActionProvider;
    private File mSharedOutputFile = null;

    private boolean mSharingImage = false;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
@@ -210,6 +222,46 @@ public class FilterShowActivity extends Activity implements OnItemClickListener
        }
    }

    public void completeSaveImage(Uri saveUri) {
        if (mSharingImage && mSharedOutputFile != null) {
            // Image saved, we unblock the content provider
            Uri uri = Uri.withAppendedPath(SharedImageProvider.CONTENT_URI,
                    Uri.encode(mSharedOutputFile.getAbsolutePath()));
            ContentValues values = new ContentValues();
            values.put(SharedImageProvider.PREPARE, false);
            getContentResolver().insert(uri, values);
        }
        setResult(RESULT_OK, new Intent().setData(saveUri));
        finish();
    }

    @Override
    public boolean onShareTargetSelected(ShareActionProvider arg0, Intent arg1) {
        // First, let's tell the SharedImageProvider that it will need to wait for the image
        Uri uri = Uri.withAppendedPath(SharedImageProvider.CONTENT_URI,
                Uri.encode(mSharedOutputFile.getAbsolutePath()));
        ContentValues values = new ContentValues();
        values.put(SharedImageProvider.PREPARE, true);
        getContentResolver().insert(uri, values);
        mSharingImage = true;

        // Process and save the image in the background.
        mImageShow.saveImage(this, mSharedOutputFile);
        return true;
    }

    private Intent getDefaultShareIntent() {
        Intent intent = new Intent(Intent.ACTION_SEND);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        intent.setType(SharedImageProvider.MIME_TYPE);
        mSharedOutputFile = SaveCopyTask.getNewFile(this, mImageLoader.getUri());
        Uri uri = Uri.withAppendedPath(SharedImageProvider.CONTENT_URI,
                Uri.encode(mSharedOutputFile.getAbsolutePath()));
        intent.putExtra(Intent.EXTRA_STREAM, uri);
        return intent;
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.filtershow_activity_menu, menu);
@@ -225,6 +277,10 @@ public class FilterShowActivity extends Activity implements OnItemClickListener
        } else {
            showState.setTitle(R.string.show_imagestate_panel);
        }
        mShareActionProvider = (ShareActionProvider) menu.findItem(R.id.menu_share)
                .getActionProvider();
        mShareActionProvider.setShareIntent(getDefaultShareIntent());
        mShareActionProvider.setOnShareTargetSelectedListener(this);
        return true;
    }

@@ -865,12 +921,7 @@ public class FilterShowActivity extends Activity implements OnItemClickListener
        toast.setGravity(Gravity.CENTER, 0, 0);
        toast.show();

        mImageShow.saveImage(this);
    }

    public void completeSaveImage(Uri saveUri) {
        setResult(RESULT_OK, new Intent().setData(saveUri));
        finish();
        mImageShow.saveImage(this, null);
    }

    static {
+11 −4
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@
package com.android.gallery3d.filtershow.cache;

import java.io.Closeable;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
@@ -13,6 +14,7 @@ import com.android.gallery3d.filtershow.HistoryAdapter;
import com.android.gallery3d.filtershow.imageshow.ImageShow;
import com.android.gallery3d.filtershow.presets.ImagePreset;
import com.android.gallery3d.filtershow.tools.SaveCopyTask;
import com.android.gallery3d.filtershow.tools.ProcessedBitmap;
import com.android.gallery3d.R;

import android.content.Context;
@@ -59,6 +61,10 @@ public class ImageLoader {
        updateBitmaps();
    }

    public Uri getUri() {
        return mUri;
    }

    private int getOrientation(Uri uri) {
        Cursor cursor = null;
        try {
@@ -219,7 +225,8 @@ public class ImageLoader {
        mCache.reset(imagePreset);
    }

    public Uri saveImage(ImagePreset preset, final FilterShowActivity filterShowActivity) {
    public Uri saveImage(ImagePreset preset, final FilterShowActivity filterShowActivity,
            File destination) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inMutable = true;

@@ -235,15 +242,15 @@ public class ImageLoader {
            // TODO: on <3.x we need a copy of the bitmap (inMutable doesn't
            // exist)
            mSaveCopy = mFullOriginalBitmap;
            preset.apply(mSaveCopy);
            new SaveCopyTask(mContext, mUri, new SaveCopyTask.Callback() {
            ProcessedBitmap processedBitmap = new ProcessedBitmap(mSaveCopy, preset);
            new SaveCopyTask(mContext, mUri, destination, new SaveCopyTask.Callback() {

                @Override
                public void onComplete(Uri result) {
                    filterShowActivity.completeSaveImage(result);
                }

            }).execute(mSaveCopy);
            }).execute(processedBitmap);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
+4 −2
Original line number Diff line number Diff line
@@ -13,6 +13,8 @@ import com.android.gallery3d.R;
import com.android.gallery3d.R.id;
import com.android.gallery3d.R.layout;

import java.io.File;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
@@ -288,8 +290,8 @@ public class ImageShow extends View implements SliderListener {
        mFilteredImage = bitmap;
    }

    public void saveImage(FilterShowActivity filterShowActivity) {
        mImageLoader.saveImage(getImagePreset(), filterShowActivity);
    public void saveImage(FilterShowActivity filterShowActivity, File file) {
        mImageLoader.saveImage(getImagePreset(), filterShowActivity, file);
    }

    public boolean onTouchEvent(MotionEvent event) {
+123 −0
Original line number Diff line number Diff line

package com.android.gallery3d.filtershow.provider;

import android.content.ContentProvider;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.net.Uri;
import android.os.ConditionVariable;
import android.os.ParcelFileDescriptor;
import android.provider.BaseColumns;
import android.provider.MediaStore;
import android.provider.OpenableColumns;
import android.util.Log;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Arrays;

public class SharedImageProvider extends ContentProvider {

    private static final String LOGTAG = "SharedImageProvider";

    public static final String MIME_TYPE = "image/jpeg";
    public static final String AUTHORITY = "com.android.gallery3d.filtershow.provider.SharedImageProvider";
    public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/image");
    public static final String PREPARE = "prepare";

    private final String[] mMimeStreamType = {
            MIME_TYPE
    };

    private static ConditionVariable mImageReadyCond = new ConditionVariable(false);

    @Override
    public int delete(Uri arg0, String arg1, String[] arg2) {
        return 0;
    }

    @Override
    public String getType(Uri arg0) {
        return MIME_TYPE;
    }

    @Override
    public String[] getStreamTypes(Uri arg0, String mimeTypeFilter) {
        return mMimeStreamType;
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        if (values.containsKey(PREPARE)) {
            if (values.getAsBoolean(PREPARE)) {
                mImageReadyCond.close();
            } else {
                mImageReadyCond.open();
            }
        }
        return null;
    }

    @Override
    public int update(Uri arg0, ContentValues arg1, String arg2, String[] arg3) {
        return 0;
    }

    @Override
    public boolean onCreate() {
        return true;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
        String uriPath = uri.getLastPathSegment();
        if (uriPath == null) {
            return null;
        }
        if (projection == null) {
            projection = new String[] {
                    BaseColumns._ID,
                    MediaStore.MediaColumns.DATA,
                    OpenableColumns.DISPLAY_NAME,
                    OpenableColumns.SIZE
            };
        }
        // If we receive a query on display name or size,
        // we should block until the image is ready
        mImageReadyCond.block();

        File path = new File(uriPath);

        MatrixCursor cursor = new MatrixCursor(projection);
        Object[] columns = new Object[projection.length];
        for (int i = 0; i < projection.length; i++) {
            if (projection[i].equalsIgnoreCase(BaseColumns._ID)) {
                columns[i] = 0;
            } else if (projection[i].equalsIgnoreCase(MediaStore.MediaColumns.DATA)) {
                columns[i] = uri;
            } else if (projection[i].equalsIgnoreCase(OpenableColumns.DISPLAY_NAME)) {
                columns[i] = path.getName();
            } else if (projection[i].equalsIgnoreCase(OpenableColumns.SIZE)) {
                columns[i] = path.length();
            }
        }
        cursor.addRow(columns);

        return cursor;
    }

    public ParcelFileDescriptor openFile(Uri uri, String mode)
            throws FileNotFoundException {
        String uriPath = uri.getLastPathSegment();
        if (uriPath == null) {
            return null;
        }
        // Here we need to block until the image is ready
        mImageReadyCond.block();
        File path = new File(uriPath);
        int imode = 0;
        imode |= ParcelFileDescriptor.MODE_READ_ONLY;
        return ParcelFileDescriptor.open(path, imode);
    }
}
Loading