RFR: 8314070: javax.print: Support IPP output-bin attribute extension [v10]

Alexander Scherbatiy alexsch at openjdk.org
Tue May 21 20:12:08 UTC 2024


On Tue, 21 May 2024 19:01:35 GMT, Alexander Scherbatiy <alexsch at openjdk.org> wrote:

>> The fix adds new public `OutputBin` print attribute class which allow to set a printer output bin in a `PrinterJob` class. The corresponding internal `CustomOutputBin` class is added as well.
>> 
>> - Constants used in `OutputBin` class are based on [Internet Printing Protocol (IPP): “output-bin” attribute extension](https://ftp.pwg.org/pub/pwg/candidates/cs-ippoutputbin10-20010207-5100.2.pdf) document.
>> - `CUPSPrinter.getOutputBins(String printer)` method uses PPD  `ppdFindOption(..., "OutputBin")` function to get supported output bins for the given printer on native level.
>> - The fix propagates the `OutputBin` attribute from the printer job attributes to `NSPrintInfo` print settings with `OutputBin` key on macOS.
>> 
>> The fix was tested on `Kyocera ECOSYS M8130cidn` printer where `ppdFindOption(..., "OutputBin")` call returns 4 output bins (text, choice): 
>> - Printer settings, None
>> - Inner tray, INNERTRAY
>> - Separator tray, SEPARATORTRAY
>> - Finisher (face-down), Main
>> 
>> if `Printer settings`, `Inner tray`, or `Finisher (face-down)` CustomOutputBins is set to `PrinterJob.print(...)` attributes a test page is printed to the Main tray of the  `Kyocera ECOSYS M8130cidn` printer. If `Separator tray` is used a page is printed to the Separator tray. This is consistent with the printer behavior when a native print dialog is used from a native Preview app to print a document on macOS.
>
> Alexander Scherbatiy has updated the pull request incrementally with one additional commit since the last revision:
> 
>   Add OutputBin support on Linux

The fix is updated to include OutputBins support on Linux.
The list of supported output bins is retrieved from ipp on Linux and the `-o output-bin=<output-bin>` lpr option is used to pass the selected output bin to the printer.

The OutputBin values are retrieved from cups on MacOS as in the initial fix.
First, it is not clear how to provide output bins in ipp format to NSPrintInfo on Mac OS.
Second, selecting an output bin in native MacOS dialog is listed in the NSPrintInfo print settings with `OutputBin` key and cups format value. It seems the cups output bins support is necessary on MacOS in any way.

The fix was tested with Kyocera ECOSYS M8130cidn printer which has 2 output trays and the number of the output trays and names of output bins on a native Print dialog depends on operation system and used drivers.

Linux:
`PrintService.getSupportedAttributeValues(OutputBin.class, null, null)` returns 2 output bins in ipp format: `top` and `stacker-1`.
Both tests `OutputBinAttributeTest` (print a test page without a Print dialg and iterating over all supported output bins) and `OutputBinAttributePrintDialogTest` (asking a user to manually select an output bin from the common Print dialog) pass: a page with `top` output bin goes to the one output tray and the `stacker-1` to another.

The `OutputBinAttributePrintDialogTest` has been updated to show only the common dialog as the common and the native dialogs are the same on Linux. 

MacOS:
It was found that the location of output bins on the native Print dialog depends on the printer driver and the way how it is installed.

Two ways were tested.
1. Installing the printer with selecting `Secure Air Print` on the `Add Printer` dialog.
In this way for the installed `Kyocera ECOSYS M8130cidn` printer 
`PrintService.getSupportedAttributeValues(OutputBin.class, null, null)` returns 2 output bins in cups format: `Top` and `Stacker 1`.
Both tests `OutputBinAttributeTest` and `OutputBinAttributePrintDialogTest` pass.

The MacOS native dialog includes `Finishing Options` with list of output bins as it is shown on the screenshot:

![ecosys-m8130cidn-secure-air-print](https://github.com/openjdk/jdk/assets/23520046/90644f83-ceda-46af-8393-a2aba000481f)

2. Installing the printer with selecting `Kyocera Classic Universal Printer Driver (KPDL)` on the `Add Printer` dialog.
`PrintService.getSupportedAttributeValues(OutputBin.class, null, null)` returns 4 output bins in cups format: `Printer settings`, `Inner tray`, `Separator tray`, and `Finisher (face-down)`.
The tests `OutputBinAttributeTest` and `OutputBinAttributePrintDialogTest` with the common dialog pass and the test  `OutputBinAttributePrintDialogTest` with the native dialog fails.

The `KPDL` driver uses a separate `Print Panel` for output tray options (see screenshots where the first one is the native MacOS dialog with the `Print Panel` option and the second dialog is the `Print Panel` option where output bins are listed under the destination category:
![ecosys-m8130cidn-kpdl-print-dialog](https://github.com/openjdk/jdk/assets/23520046/d7c921b1-979e-4736-81b4-b0d59e13ea95)
![ecosys-m8130cidn-kpdl-print-panel](https://github.com/openjdk/jdk/assets/23520046/884f03ee-22eb-43de-8be5-625102da2218)

Actually the `OutputBinAttributePrintDialogTest` does not use output bins to put them to the dialog. It only asks a user to select the tested output bin from the dialog. So the simple java program [PrintNativeDialog](https://cr.openjdk.org/~alexsch/printer/tests/PrintNativeDialog.java) has been written which does not use output bins to print a test page (in the same way as it does the `OutputBinAttributePrintDialogTest`).
Both of them use the following logic:

        PrintService service = PrintServiceLookup.lookupDefaultPrintService();
        System.out.printf("Default service: %s%n", service);

        PrintRequestAttributeSet attr = new HashPrintRequestAttributeSet();
        attr.add(DialogTypeSelection.NATIVE);

        for (Attribute attribute : attr.toArray()) {
            System.out.printf("Print request attribute: %s%n", attribute);
        }

        PrinterJob job = PrinterJob.getPrinterJob();
        TextPrintable textPrintable = new TextPrintable("Hello, World!");
        job.setPrintable(textPrintable);

        if (job.printDialog(attr)) {
            job.print();
        }

The test [PrintNativeDialog](https://cr.openjdk.org/~alexsch/printer/tests/PrintNativeDialog.java) has been compiled by jdk 21.0.3+12-LTS (it does not include the fix with the output bins) and it was found that using the same steps (selecting the output bins from the Print Panel destination category) prints all pages to the same output tray.
So, the jdk with the fix works in the same way as the jdk 21 without the fix in this case.

The debug showed that the resulting `NSPrintInfo` does not contain the `OutputBin` key in the print settings when the `(KPDL)` printer with the separated `Print Panel` is used to manually select an output bin.

The native dialog has been added together with the common dialog for the `OutputBinAttributePrintDialogTest` just to cover both dialogs types. It looks like the native dialog does not use any improvements from the current fix (fix does not put output bins to the NSPrintInfo and does not read from it) in the `OutputBinAttributePrintDialogTest` with the native dialog test. The test with the native dialog works with the `Secure Air Print` because it puts the chosen output bins to NSPrintInfo print settings and then this NSPrintInfo is reused. The `PrintNativeDialog` works in the same way for these two setups does not matter is jdk with the fix or without the fix is used.

The another issue with the native dialog in the `OutputBinAttributePrintDialogTest` test is that the list of output trays can be listed in different places and some of them can be disabled.

What should be the right way to properly handle the  `OutputBinAttributePrintDialogTest` test  with the native dialog option?

-------------

PR Comment: https://git.openjdk.org/jdk/pull/16166#issuecomment-2123361160


More information about the client-libs-dev mailing list