summaryrefslogtreecommitdiffstats
path: root/packages/PrintSpooler
diff options
context:
space:
mode:
authorSvetoslav <svetoslavganov@google.com>2015-02-02 19:47:04 -0800
committerSvetoslav Ganov <svetoslavganov@google.com>2015-02-04 05:48:48 +0000
commit948c9a6393e0995a4d988d5d164998aa0e12b25d (patch)
tree8ff11da699702a25b697074c2ce7e181cb2593b6 /packages/PrintSpooler
parentd7596cff0b61a58e089f76bee3c626486bcbaec7 (diff)
downloadframeworks_base-948c9a6393e0995a4d988d5d164998aa0e12b25d.zip
frameworks_base-948c9a6393e0995a4d988d5d164998aa0e12b25d.tar.gz
frameworks_base-948c9a6393e0995a4d988d5d164998aa0e12b25d.tar.bz2
Add duplex mode support.
This change adds support for duplex printing. The print UI now has a duplex option which allows the user to choose one of the supported duplex options by the currently selected printer. The chosen duplex mode is propaged to the print service that manages this printer. Change-Id: I807ba9da2723531535c0e1e33f2f4e1b503a54b0
Diffstat (limited to 'packages/PrintSpooler')
-rw-r--r--packages/PrintSpooler/res/layout/print_activity_controls.xml28
-rw-r--r--packages/PrintSpooler/res/values/strings.xml15
-rw-r--r--packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java11
-rw-r--r--packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java108
4 files changed, 160 insertions, 2 deletions
diff --git a/packages/PrintSpooler/res/layout/print_activity_controls.xml b/packages/PrintSpooler/res/layout/print_activity_controls.xml
index 0bf64aa..a87afe0 100644
--- a/packages/PrintSpooler/res/layout/print_activity_controls.xml
+++ b/packages/PrintSpooler/res/layout/print_activity_controls.xml
@@ -159,6 +159,34 @@
android:layout_marginEnd="16dip"
android:orientation="vertical">
+ <!-- Duplex -->
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="8dip"
+ android:layout_marginStart="12dip"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:labelFor="@+id/duplex_spinner"
+ android:text="@string/label_duplex">
+ </TextView>
+
+ <Spinner
+ android:id="@+id/duplex_spinner"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="4dip">
+ </Spinner>
+
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="16dip"
+ android:layout_marginEnd="16dip"
+ android:orientation="vertical">
+
<!-- Range options -->
<TextView
diff --git a/packages/PrintSpooler/res/values/strings.xml b/packages/PrintSpooler/res/values/strings.xml
index ab633ea..9d67ccc 100644
--- a/packages/PrintSpooler/res/values/strings.xml
+++ b/packages/PrintSpooler/res/values/strings.xml
@@ -40,6 +40,9 @@
<!-- Label of the color mode widget. [CHAR LIMIT=20] -->
<string name="label_color">Color</string>
+ <!-- Label of the duplex mode widget. [CHAR LIMIT=20] -->
+ <string name="label_duplex">Duplex</string>
+
<!-- Label of the orientation widget. [CHAR LIMIT=20] -->
<string name="label_orientation">Orientation</string>
@@ -188,12 +191,22 @@
<!-- Color mode labels. -->
<string-array name="color_mode_labels">
- <!-- Color modelabel: Monochrome color scheme, e.g. one color is used. [CHAR LIMIT=20] -->
+ <!-- Color mode label: Monochrome color scheme, e.g. one color is used. [CHAR LIMIT=20] -->
<item>Black &amp; White</item>
<!-- Color mode label: Color color scheme, e.g. many colors are used. [CHAR LIMIT=20] -->
<item>Color</item>
</string-array>
+ <!-- Duplex mode labels. -->
+ <string-array name="duplex_mode_labels">
+ <!-- Duplex mode label: No duplex supported. [CHAR LIMIT=20] -->
+ <item>None</item>
+ <!-- Duplex mode label: Turn page sideways along the long edge like a book. [CHAR LIMIT=20] -->
+ <item>Long edge</item>
+ <!-- Duplex mode label: Turn page upwards along the short edge like a notepad. [CHAR LIMIT=20] -->
+ <item>Short edge</item>
+ </string-array>
+
<!-- Orientation labels. -->
<string-array name="orientation_labels">
<!-- Orientation label: Portrait page orientation. [CHAR LIMIT=30] -->
diff --git a/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java b/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java
index 2cc5e04..377d2d5 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java
@@ -695,6 +695,7 @@ public final class PrintSpoolerService extends Service {
private static final String TAG_MARGINS = "margins";
private static final String ATTR_COLOR_MODE = "colorMode";
+ private static final String ATTR_DUPLEX_MODE = "duplexMode";
private static final String ATTR_LOCAL_ID = "localId";
private static final String ATTR_SERVICE_NAME = "serviceName";
@@ -823,6 +824,10 @@ public final class PrintSpoolerService extends Service {
serializer.attribute(null, ATTR_COLOR_MODE,
String.valueOf(colorMode));
+ final int duplexMode = attributes.getDuplexMode();
+ serializer.attribute(null, ATTR_DUPLEX_MODE,
+ String.valueOf(duplexMode));
+
MediaSize mediaSize = attributes.getMediaSize();
if (mediaSize != null) {
serializer.startTag(null, TAG_MEDIA_SIZE);
@@ -1057,6 +1062,12 @@ public final class PrintSpoolerService extends Service {
String colorMode = parser.getAttributeValue(null, ATTR_COLOR_MODE);
builder.setColorMode(Integer.parseInt(colorMode));
+ String duplexMode = parser.getAttributeValue(null, ATTR_DUPLEX_MODE);
+ // Duplex mode was added later, so null check is needed.
+ if (duplexMode != null) {
+ builder.setDuplexMode(Integer.parseInt(duplexMode));
+ }
+
parser.next();
skipEmptyTextTags(parser);
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
index f3a5c95..4ba04e5 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
@@ -184,6 +184,9 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat
private Spinner mColorModeSpinner;
private ArrayAdapter<SpinnerItem<Integer>> mColorModeSpinnerAdapter;
+ private Spinner mDuplexModeSpinner;
+ private ArrayAdapter<SpinnerItem<Integer>> mDuplexModeSpinnerAdapter;
+
private Spinner mOrientationSpinner;
private ArrayAdapter<SpinnerItem<Integer>> mOrientationSpinnerAdapter;
@@ -767,6 +770,21 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat
}
}
}
+
+ // Take the duplex mode only if the current printer supports it.
+ final int currDuplexMode = currAttributes.getDuplexMode();
+ final int newDuplexMode = newAttributes.getDuplexMode();
+ if (currDuplexMode != newDuplexMode) {
+ final int duplexModeCount = mDuplexModeSpinner.getCount();
+ for (int i = 0; i < duplexModeCount; i++) {
+ final int supportedDuplexMode = mDuplexModeSpinnerAdapter.getItem(i).value;
+ if (supportedDuplexMode == newDuplexMode) {
+ currAttributes.setDuplexMode(newDuplexMode);
+ mDuplexModeSpinner.setSelection(i);
+ break;
+ }
+ }
+ }
}
// Handle selected page changes making sure they are in the doc.
@@ -985,6 +1003,12 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat
attributes.setColorMode(defaults.getColorMode());
}
+ // Duplex mode.
+ final int duplexMode = attributes.getDuplexMode();
+ if ((capabilities.getDuplexModes() & duplexMode) == 0) {
+ attributes.setDuplexMode(defaults.getDuplexMode());
+ }
+
// Resolution
Resolution resolution = attributes.getResolution();
if (resolution == null || !capabilities.getResolutions().contains(resolution)) {
@@ -1111,6 +1135,13 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat
mColorModeSpinner.setAdapter(mColorModeSpinnerAdapter);
mColorModeSpinner.setOnItemSelectedListener(itemSelectedListener);
+ // Duplex mode.
+ mDuplexModeSpinnerAdapter = new ArrayAdapter<>(
+ this, android.R.layout.simple_spinner_dropdown_item, android.R.id.text1);
+ mDuplexModeSpinner = (Spinner) findViewById(R.id.duplex_spinner);
+ mDuplexModeSpinner.setAdapter(mDuplexModeSpinnerAdapter);
+ mDuplexModeSpinner.setOnItemSelectedListener(itemSelectedListener);
+
// Orientation
mOrientationSpinnerAdapter = new ArrayAdapter<>(
this, android.R.layout.simple_spinner_dropdown_item, android.R.id.text1);
@@ -1187,6 +1218,7 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat
mCopiesEditText.setFocusable(false);
mMediaSizeSpinner.setEnabled(false);
mColorModeSpinner.setEnabled(false);
+ mDuplexModeSpinner.setEnabled(false);
mOrientationSpinner.setEnabled(false);
mRangeOptionsSpinner.setEnabled(false);
mPageRangeEditText.setEnabled(false);
@@ -1202,6 +1234,7 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat
mCopiesEditText.setFocusable(false);
mMediaSizeSpinner.setEnabled(false);
mColorModeSpinner.setEnabled(false);
+ mDuplexModeSpinner.setEnabled(false);
mOrientationSpinner.setEnabled(false);
mRangeOptionsSpinner.setEnabled(false);
mPageRangeEditText.setEnabled(false);
@@ -1317,7 +1350,7 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat
final int colorMode = 1 << colorBitOffset;
if (colorMode == oldColorMode) {
// Update the index of the old selection.
- oldColorModeNewIndex = colorBitOffset;
+ oldColorModeNewIndex = mColorModeSpinnerAdapter.getCount();
}
remainingColorModes &= ~colorMode;
mColorModeSpinnerAdapter.add(new SpinnerItem<>(colorMode,
@@ -1339,11 +1372,81 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat
mColorModeSpinner.setSelection(i);
}
attributes.setColorMode(selectedColorMode);
+ break;
}
}
}
}
+ // Duplex mode.
+ mDuplexModeSpinner.setEnabled(true);
+ final int duplexModes = capabilities.getDuplexModes();
+
+ // If the duplex modes changed, we update the adapter and the spinner.
+ // Note that we use bit count +1 to account for the no duplex option.
+ boolean duplexModesChanged = false;
+ if (Integer.bitCount(duplexModes) != mDuplexModeSpinnerAdapter.getCount()) {
+ duplexModesChanged = true;
+ } else {
+ int remainingDuplexModes = duplexModes;
+ int adapterIndex = 0;
+ while (remainingDuplexModes != 0) {
+ final int duplexBitOffset = Integer.numberOfTrailingZeros(remainingDuplexModes);
+ final int duplexMode = 1 << duplexBitOffset;
+ remainingDuplexModes &= ~duplexMode;
+ if (duplexMode != mDuplexModeSpinnerAdapter.getItem(adapterIndex).value) {
+ duplexModesChanged = true;
+ break;
+ }
+ adapterIndex++;
+ }
+ }
+ if (duplexModesChanged) {
+ // Remember the old duplex mode to try selecting it again. Also the fallback
+ // is no duplexing which is always the first item in the dropdown.
+ int oldDuplexModeNewIndex = AdapterView.INVALID_POSITION;
+ final int oldDuplexMode = attributes.getDuplexMode();
+
+ // Rebuild the adapter data.
+ mDuplexModeSpinnerAdapter.clear();
+ String[] duplexModeLabels = getResources().getStringArray(R.array.duplex_mode_labels);
+ int remainingDuplexModes = duplexModes;
+ while (remainingDuplexModes != 0) {
+ final int duplexBitOffset = Integer.numberOfTrailingZeros(remainingDuplexModes);
+ final int duplexMode = 1 << duplexBitOffset;
+ if (duplexMode == oldDuplexMode) {
+ // Update the index of the old selection.
+ oldDuplexModeNewIndex = mDuplexModeSpinnerAdapter.getCount();
+ }
+ remainingDuplexModes &= ~duplexMode;
+ mDuplexModeSpinnerAdapter.add(new SpinnerItem<>(duplexMode,
+ duplexModeLabels[duplexBitOffset]));
+ }
+
+ if (oldDuplexModeNewIndex != AdapterView.INVALID_POSITION) {
+ // Select the old duplex mode - nothing really changed.
+ if (mDuplexModeSpinner.getSelectedItemPosition() != oldDuplexModeNewIndex) {
+ mDuplexModeSpinner.setSelection(oldDuplexModeNewIndex);
+ }
+ } else {
+ // Select the default.
+ final int selectedDuplexMode = defaultAttributes.getDuplexMode();
+ final int itemCount = mDuplexModeSpinnerAdapter.getCount();
+ for (int i = 0; i < itemCount; i++) {
+ SpinnerItem<Integer> item = mDuplexModeSpinnerAdapter.getItem(i);
+ if (selectedDuplexMode == item.value) {
+ if (mDuplexModeSpinner.getSelectedItemPosition() != i) {
+ mDuplexModeSpinner.setSelection(i);
+ }
+ attributes.setDuplexMode(selectedDuplexMode);
+ break;
+ }
+ }
+ }
+ }
+
+ mDuplexModeSpinner.setEnabled(mDuplexModeSpinnerAdapter.getCount() > 1);
+
// Orientation
mOrientationSpinner.setEnabled(true);
MediaSize mediaSize = attributes.getMediaSize();
@@ -2173,6 +2276,9 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat
} else if (spinner == mColorModeSpinner) {
SpinnerItem<Integer> colorModeItem = mColorModeSpinnerAdapter.getItem(position);
mPrintJob.getAttributes().setColorMode(colorModeItem.value);
+ } else if (spinner == mDuplexModeSpinner) {
+ SpinnerItem<Integer> duplexModeItem = mDuplexModeSpinnerAdapter.getItem(position);
+ mPrintJob.getAttributes().setDuplexMode(duplexModeItem.value);
} else if (spinner == mOrientationSpinner) {
SpinnerItem<Integer> orientationItem = mOrientationSpinnerAdapter.getItem(position);
PrintAttributes attributes = mPrintJob.getAttributes();