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

Commit 391e4a19 authored by Svetoslav Ganov's avatar Svetoslav Ganov Committed by John Hoford
Browse files

Switch Gallery2 to use the support lib for printing.

Now we have a class in the support library that uses a correct internal
implemetation based on the API level. On older devices the app does
not crash and on new devices it can print. Also this class does
the heavy lifiting. Gallery2 was not using this class, rather it had
its own (obsolete) implemetation that was not taking into account the
image aspect ratio to provide a hint to the print system for the
orientation to be used.

bug:11099831
Change-Id: I4cd260614af4d9d87ec31d205ee2a5ef02ef5417
parent 47f602c3
Loading
Loading
Loading
Loading
+9 −3
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ import android.content.res.Configuration;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
import android.support.v4.print.PrintHelper;
import android.view.Menu;
import android.view.MenuItem;
import android.view.Window;
@@ -45,12 +46,12 @@ import com.android.gallery3d.filtershow.cache.ImageLoader;
import com.android.gallery3d.ui.GLRoot;
import com.android.gallery3d.ui.GLRootView;
import com.android.gallery3d.util.PanoramaViewHelper;
import com.android.gallery3d.util.PrintJob;
import com.android.gallery3d.util.ThreadPool;
import com.android.photos.data.GalleryBitmapPool;

import java.io.FileNotFoundException;

public class AbstractGalleryActivity extends Activity implements GalleryContext {
    @SuppressWarnings("unused")
    private static final String TAG = "AbstractGalleryActivity";
    private GLRootView mGLRootView;
    private StateManager mStateManager;
@@ -357,6 +358,11 @@ public class AbstractGalleryActivity extends Activity implements GalleryContext
        } else {
            path = uri.getLastPathSegment();
        }
        PrintJob.printBitmapAtUri(this, path, uri);
        PrintHelper printer = new PrintHelper(this);
        try {
            printer.printBitmap(path, uri);
        } catch (FileNotFoundException fnfe) {
            Log.e(TAG, "Error printing an image", fnfe);
        }
    }
}
+4 −3
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.print.PrintHelper;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.TypedValue;
@@ -117,7 +118,6 @@ import com.android.gallery3d.filtershow.tools.XmpPresets.XMresults;
import com.android.gallery3d.filtershow.ui.ExportDialog;
import com.android.gallery3d.filtershow.ui.FramedTextButton;
import com.android.gallery3d.util.GalleryUtils;
import com.android.gallery3d.util.PrintJob;
import com.android.photos.data.GalleryBitmapPool;

import java.io.File;
@@ -994,7 +994,7 @@ public class FilterShowActivity extends FragmentActivity implements OnItemClickL
        MenuItem redoItem = mMenu.findItem(R.id.redoButton);
        MenuItem resetItem = mMenu.findItem(R.id.resetHistoryButton);
        MenuItem printItem = mMenu.findItem(R.id.printButton);
        if (!PrintJob.systemSupportsPrint()) {
        if (!PrintHelper.systemSupportsPrint()) {
            printItem.setVisible(false);
        }
        mMasterImage.getHistory().setMenuItems(undoItem, redoItem, resetItem);
@@ -1068,7 +1068,8 @@ public class FilterShowActivity extends FragmentActivity implements OnItemClickL

    public void print() {
        Bitmap bitmap = MasterImage.getImage().getHighresImage();
        PrintJob.printBitmap(this, "ImagePrint", bitmap);
        PrintHelper printer = new PrintHelper(this);
        printer.printBitmap("ImagePrint", bitmap);
    }

    public void addNewPreset() {
+2 −3
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.os.Handler;
import android.os.Message;
import android.support.v4.print.PrintHelper;
import android.view.Menu;
import android.view.MenuItem;

@@ -39,14 +40,12 @@ import com.android.gallery3d.data.Path;
import com.android.gallery3d.filtershow.crop.CropActivity;
import com.android.gallery3d.util.Future;
import com.android.gallery3d.util.GalleryUtils;
import com.android.gallery3d.util.PrintJob;
import com.android.gallery3d.util.ThreadPool.Job;
import com.android.gallery3d.util.ThreadPool.JobContext;

import java.util.ArrayList;

public class MenuExecutor {
    @SuppressWarnings("unused")
    private static final String TAG = "MenuExecutor";

    private static final int MSG_TASK_COMPLETE = 1;
@@ -179,7 +178,7 @@ public class MenuExecutor {
        boolean supportEdit = (supported & MediaObject.SUPPORT_EDIT) != 0;
        boolean supportInfo = (supported & MediaObject.SUPPORT_INFO) != 0;
        boolean supportPrint = (supported & MediaObject.SUPPORT_PRINT) != 0;
        supportPrint &= PrintJob.systemSupportsPrint();
        supportPrint &= PrintHelper.systemSupportsPrint();

        setMenuItemVisible(menu, R.id.action_delete, supportDelete);
        setMenuItemVisible(menu, R.id.action_rotate_ccw, supportRotate);
+0 −160
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.gallery3d.util;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.graphics.RectF;
import android.graphics.pdf.PdfDocument.Page;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.ParcelFileDescriptor;
import android.print.PageRange;
import android.print.PrintAttributes;
import android.print.PrintDocumentAdapter;
import android.print.PrintDocumentInfo;
import android.print.PrintManager;
import android.print.pdf.PrintedPdfDocument;

import com.android.gallery3d.filtershow.cache.ImageLoader;

import java.io.FileOutputStream;
import java.io.IOException;

public class PrintJob {
    private static final String LOG_TAG = "PrintJob";
    private static final boolean CROP_TO_FILL_PAGE = true;
    // will be <= 300 dpi on A4 (8.3×11.7) paper
    // with a worst case of 150 dpi
    private final static int MAX_PRINT_SIZE = 3500;
    static Boolean sNoPrint = null;

    /**
     * @return true if the system supports print
     */
    public static boolean systemSupportsPrint() {
        // TODO change the code to call a support library
        if (sNoPrint != null) {
            return sNoPrint;
        }
        try {
            Class c = Class.forName("android.print.PrintManager");
            sNoPrint = true;
        } catch (ClassNotFoundException e) {
            sNoPrint = false;
        }
        return sNoPrint;
    }

    public static void printBitmap(final Context context, final String jobName,
                                   final Bitmap bitmap) {
        if (bitmap == null) {
            return;
        }
        PrintManager printManager = (PrintManager) context.getSystemService(Context.PRINT_SERVICE);
        printManager.print(jobName,
                new PrintDocumentAdapter() {
                    private PrintAttributes mAttributes;

                    @Override
                    public void onLayout(PrintAttributes oldPrintAttributes,
                                         PrintAttributes newPrintAttributes,
                                         CancellationSignal cancellationSignal,
                                         LayoutResultCallback layoutResultCallback,
                                         Bundle bundle) {

                        mAttributes = newPrintAttributes;

                        PrintDocumentInfo info = new PrintDocumentInfo.Builder(jobName)
                                .setContentType(PrintDocumentInfo.CONTENT_TYPE_PHOTO)
                                .setPageCount(1)
                                .build();
                        boolean changed = !newPrintAttributes.equals(oldPrintAttributes);
                        layoutResultCallback.onLayoutFinished(info, changed);
                    }

                    @Override
                    public void onWrite(PageRange[] pageRanges, ParcelFileDescriptor fileDescriptor,
                                        CancellationSignal cancellationSignal,
                                        WriteResultCallback writeResultCallback) {
                        PrintedPdfDocument pdfDocument = new PrintedPdfDocument(context,
                                mAttributes);
                        try {
                            Page page = pdfDocument.startPage(1);

                            RectF content = new RectF(page.getInfo().getContentRect());
                            Matrix matrix = new Matrix();

                            // Compute and apply scale to fill the page.
                            float scale = content.width() / bitmap.getWidth();
                            if (CROP_TO_FILL_PAGE) {
                                scale = Math.max(scale, content.height() / bitmap.getHeight());
                            } else {
                                scale = Math.min(scale, content.height() / bitmap.getHeight());
                            }
                            matrix.postScale(scale, scale);

                            // Center the content.
                            final float translateX = (content.width()
                                    - bitmap.getWidth() * scale) / 2;
                            final float translateY = (content.height()
                                    - bitmap.getHeight() * scale) / 2;
                            matrix.postTranslate(translateX, translateY);

                            // Draw the bitmap.
                            page.getCanvas().drawBitmap(bitmap, matrix, null);

                            // Finish the page.
                            pdfDocument.finishPage(page);

                            try {
                                // Write the document.
                                pdfDocument.writeTo(new FileOutputStream(
                                        fileDescriptor.getFileDescriptor()));
                                // Done.
                                writeResultCallback.onWriteFinished(
                                        new PageRange[]{PageRange.ALL_PAGES});
                            } catch (IOException ioe) {
                                // Failed.
                                Log.e(LOG_TAG, "Error writing printed content", ioe);
                                writeResultCallback.onWriteFailed(null);
                            }
                        } finally {
                            if (pdfDocument != null) {
                                pdfDocument.close();
                            }
                            if (fileDescriptor != null) {
                                try {
                                    fileDescriptor.close();
                                } catch (IOException ioe) {
                                    /* ignore */
                                }
                            }
                        }
                    }
                }, null);
    }

    public static void printBitmapAtUri(Context context, String imagePrint, Uri uri) {
        // TODO: load full size images. For now, it's better to constrain ourselves.
        Bitmap bitmap = ImageLoader.loadConstrainedBitmap(uri, context, MAX_PRINT_SIZE, null, false);
        printBitmap(context, imagePrint, bitmap);
    }
}