summaryrefslogtreecommitdiffstats
path: root/packages/PrintSpooler
diff options
context:
space:
mode:
Diffstat (limited to 'packages/PrintSpooler')
-rw-r--r--packages/PrintSpooler/res/values/strings.xml6
-rw-r--r--packages/PrintSpooler/src/com/android/printspooler/FusedPrintersProvider.java109
-rw-r--r--packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java1
-rw-r--r--packages/PrintSpooler/src/com/android/printspooler/SelectPrinterFragment.java71
4 files changed, 170 insertions, 17 deletions
diff --git a/packages/PrintSpooler/res/values/strings.xml b/packages/PrintSpooler/res/values/strings.xml
index f2e768a..d2613d0 100644
--- a/packages/PrintSpooler/res/values/strings.xml
+++ b/packages/PrintSpooler/res/values/strings.xml
@@ -93,6 +93,12 @@
<!-- Title of the action bar button to got to add a printer. [CHAR LIMIT=25] -->
<string name="print_add_printer">Add printer</string>
+ <!-- Title of the menu item to select a printer. [CHAR LIMIT=25] -->
+ <string name="print_select_printer">Select printer</string>
+
+ <!-- Title of the menu item to forget a printer. [CHAR LIMIT=25] -->
+ <string name="print_forget_printer">Forget printer</string>
+
<!-- Utterance to announce a change in the number of matches during a search. This is spoken to a blind user. [CHAR LIMIT=none] -->
<plurals name="print_search_result_count_utterance">
<item quantity="one"><xliff:g id="count" example="1">%1$s</xliff:g> printer found</item>
diff --git a/packages/PrintSpooler/src/com/android/printspooler/FusedPrintersProvider.java b/packages/PrintSpooler/src/com/android/printspooler/FusedPrintersProvider.java
index 0601467..9831839 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/FusedPrintersProvider.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/FusedPrintersProvider.java
@@ -79,6 +79,8 @@ public class FusedPrintersProvider extends Loader<List<PrinterInfo>> {
private PrinterId mTrackedPrinter;
+ private boolean mPrintersUpdatedBefore;
+
public FusedPrintersProvider(Context context) {
super(context);
mPersistenceManager = new PersistenceManager(context);
@@ -88,13 +90,14 @@ public class FusedPrintersProvider extends Loader<List<PrinterInfo>> {
mPersistenceManager.addPrinterAndWritePrinterHistory(printer);
}
- private void computeAndDeliverResult(Map<PrinterId, PrinterInfo> discoveredPrinters) {
+ private void computeAndDeliverResult(ArrayMap<PrinterId, PrinterInfo> discoveredPrinters,
+ ArrayMap<PrinterId, PrinterInfo> favoritePrinters) {
List<PrinterInfo> printers = new ArrayList<PrinterInfo>();
// Add the updated favorite printers.
- final int favoritePrinterCount = mFavoritePrinters.size();
+ final int favoritePrinterCount = favoritePrinters.size();
for (int i = 0; i < favoritePrinterCount; i++) {
- PrinterInfo favoritePrinter = mFavoritePrinters.get(i);
+ PrinterInfo favoritePrinter = favoritePrinters.valueAt(i);
PrinterInfo updatedPrinter = discoveredPrinters.remove(
favoritePrinter.getId());
if (updatedPrinter != null) {
@@ -123,8 +126,11 @@ public class FusedPrintersProvider extends Loader<List<PrinterInfo>> {
mPrinters.addAll(printers);
if (isStarted()) {
- // Deliver the printers.
+ // If stated deliver the new printers.
deliverResult(printers);
+ } else {
+ // Otherwise, take a note for the change.
+ onContentChanged();
}
}
@@ -165,6 +171,8 @@ public class FusedPrintersProvider extends Loader<List<PrinterInfo>> {
.getSystemService(Context.PRINT_SERVICE);
mDiscoverySession = printManager.createPrinterDiscoverySession();
mPersistenceManager.readPrinterHistory();
+ } else if (mPersistenceManager.isHistoryChanged()) {
+ mPersistenceManager.readPrinterHistory();
}
if (mPersistenceManager.isReadHistoryCompleted()
&& !mDiscoverySession.isPrinterDiscoveryStarted()) {
@@ -176,7 +184,7 @@ public class FusedPrintersProvider extends Loader<List<PrinterInfo>> {
+ mDiscoverySession.getPrinters().size()
+ " " + FusedPrintersProvider.this.hashCode());
}
- updatePrinters(mDiscoverySession.getPrinters());
+ updatePrinters(mDiscoverySession.getPrinters(), mFavoritePrinters);
}
});
final int favoriteCount = mFavoritePrinters.size();
@@ -187,15 +195,19 @@ public class FusedPrintersProvider extends Loader<List<PrinterInfo>> {
mDiscoverySession.startPrinterDisovery(printerIds);
List<PrinterInfo> printers = mDiscoverySession.getPrinters();
if (!printers.isEmpty()) {
- updatePrinters(printers);
+ updatePrinters(printers, mFavoritePrinters);
}
}
}
- private void updatePrinters(List<PrinterInfo> printers) {
- if (mPrinters.equals(printers)) {
+ private void updatePrinters(List<PrinterInfo> printers, List<PrinterInfo> favoritePrinters) {
+ if (mPrintersUpdatedBefore && mPrinters.equals(printers)
+ && mFavoritePrinters.equals(favoritePrinters)) {
return;
}
+
+ mPrintersUpdatedBefore = true;
+
ArrayMap<PrinterId, PrinterInfo> printersMap =
new ArrayMap<PrinterId, PrinterInfo>();
final int printerCount = printers.size();
@@ -203,7 +215,16 @@ public class FusedPrintersProvider extends Loader<List<PrinterInfo>> {
PrinterInfo printer = printers.get(i);
printersMap.put(printer.getId(), printer);
}
- computeAndDeliverResult(printersMap);
+
+ ArrayMap<PrinterId, PrinterInfo> favoritePrintersMap =
+ new ArrayMap<PrinterId, PrinterInfo>();
+ final int favoritePrinterCount = favoritePrinters.size();
+ for (int i = 0; i < favoritePrinterCount; i++) {
+ PrinterInfo favoritePrinter = favoritePrinters.get(i);
+ favoritePrintersMap.put(favoritePrinter.getId(), favoritePrinter);
+ }
+
+ computeAndDeliverResult(printersMap, favoritePrintersMap);
}
@Override
@@ -264,6 +285,42 @@ public class FusedPrintersProvider extends Loader<List<PrinterInfo>> {
}
}
+ public boolean isFavoritePrinter(PrinterId printerId) {
+ final int printerCount = mFavoritePrinters.size();
+ for (int i = 0; i < printerCount; i++) {
+ PrinterInfo favoritePritner = mFavoritePrinters.get(i);
+ if (favoritePritner.getId().equals(printerId)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public void forgetFavoritePrinter(PrinterId printerId) {
+ List<PrinterInfo> newFavoritePrinters = null;
+
+ // Remove the printer from the favorites.
+ final int favoritePrinterCount = mFavoritePrinters.size();
+ for (int i = 0; i < favoritePrinterCount; i++) {
+ PrinterInfo favoritePrinter = mFavoritePrinters.get(i);
+ if (favoritePrinter.getId().equals(printerId)) {
+ newFavoritePrinters = new ArrayList<PrinterInfo>();
+ newFavoritePrinters.addAll(mPrinters);
+ newFavoritePrinters.remove(i);
+ break;
+ }
+ }
+
+ // If we removed a favorite printer, we have work to do.
+ if (newFavoritePrinters != null) {
+ // Remove the printer from history and persist the latter.
+ mPersistenceManager.removeHistoricalPrinterAndWritePrinterHistory(printerId);
+
+ // Recompute and deliver the printers.
+ updatePrinters(mDiscoverySession.getPrinters(), newFavoritePrinters);
+ }
+ }
+
private final class PersistenceManager {
private static final String PERSIST_FILE_NAME = "printer_history.xml";
@@ -281,13 +338,15 @@ public class FusedPrintersProvider extends Loader<List<PrinterInfo>> {
private final AtomicFile mStatePersistFile;
- private List<PrinterInfo> mHistoricalPrinters;
+ private List<PrinterInfo> mHistoricalPrinters = new ArrayList<PrinterInfo>();
private boolean mReadHistoryCompleted;
private boolean mReadHistoryInProgress;
private ReadTask mReadTask;
+ private volatile long mLastReadHistoryTimestamp;
+
private PersistenceManager(Context context) {
mStatePersistFile = new AtomicFile(new File(context.getFilesDir(),
PERSIST_FILE_NAME));
@@ -327,6 +386,27 @@ public class FusedPrintersProvider extends Loader<List<PrinterInfo>> {
new ArrayList<PrinterInfo>(mHistoricalPrinters));
}
+ @SuppressWarnings("unchecked")
+ public void removeHistoricalPrinterAndWritePrinterHistory(PrinterId printerId) {
+ boolean writeHistory = false;
+ final int printerCount = mHistoricalPrinters.size();
+ for (int i = printerCount - 1; i >= 0; i--) {
+ PrinterInfo historicalPrinter = mHistoricalPrinters.get(i);
+ if (historicalPrinter.getId().equals(printerId)) {
+ mHistoricalPrinters.remove(i);
+ writeHistory = true;
+ }
+ }
+ if (writeHistory) {
+ new WriteTask().executeOnExecutor(AsyncTask.SERIAL_EXECUTOR,
+ new ArrayList<PrinterInfo>(mHistoricalPrinters));
+ }
+ }
+
+ public boolean isHistoryChanged() {
+ return mLastReadHistoryTimestamp != mStatePersistFile.getBaseFile().lastModified();
+ }
+
private List<PrinterInfo> computeFavoritePrinters(List<PrinterInfo> printers) {
Map<PrinterId, PrinterRecord> recordMap =
new ArrayMap<PrinterId, PrinterRecord>();
@@ -423,11 +503,10 @@ public class FusedPrintersProvider extends Loader<List<PrinterInfo>> {
mReadHistoryInProgress = false;
mReadHistoryCompleted = true;
- // Deliver the favorites.
- Map<PrinterId, PrinterInfo> discoveredPrinters = Collections.emptyMap();
- computeAndDeliverResult(discoveredPrinters);
+ // Deliver the printers.
+ updatePrinters(mDiscoverySession.getPrinters(), mHistoricalPrinters);
- // Start loading the available printers.
+ // Loading the available printers if needed.
loadInternal();
// We are done.
@@ -450,6 +529,8 @@ public class FusedPrintersProvider extends Loader<List<PrinterInfo>> {
XmlPullParser parser = Xml.newPullParser();
parser.setInput(in, null);
parseState(parser, printers);
+ // Take a note which version of the history was read.
+ mLastReadHistoryTimestamp = mStatePersistFile.getBaseFile().lastModified();
return printers;
} catch (IllegalStateException ise) {
Slog.w(LOG_TAG, "Failed parsing ", ise);
diff --git a/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java b/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java
index 6d0ecd7..88403a3 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java
@@ -937,6 +937,7 @@ public class PrintJobConfigActivity extends Activity {
mPrintJobId, mCurrentPrinter);
if (mCurrentPrinter.getStatus() == PrinterInfo.STATUS_UNAVAILABLE) {
+ mCapabilitiesTimeout.post();
updateUi();
return;
}
diff --git a/packages/PrintSpooler/src/com/android/printspooler/SelectPrinterFragment.java b/packages/PrintSpooler/src/com/android/printspooler/SelectPrinterFragment.java
index 204c152..fe5920c 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/SelectPrinterFragment.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/SelectPrinterFragment.java
@@ -46,6 +46,8 @@ import android.printservice.PrintServiceInfo;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
+import android.view.ContextMenu;
+import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
@@ -54,6 +56,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityManager;
import android.widget.AdapterView;
+import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.Filter;
@@ -81,6 +84,8 @@ public final class SelectPrinterFragment extends Fragment {
private static final String FRAGMRNT_ARGUMENT_PRINT_SERVICE_INFOS =
"FRAGMRNT_ARGUMENT_PRINT_SERVICE_INFOS";
+ private static final String EXTRA_PRINTER_ID = "EXTRA_PRINTER_ID";
+
private final ArrayList<PrintServiceInfo> mAddPrinterServices =
new ArrayList<PrintServiceInfo>();
@@ -127,6 +132,9 @@ public final class SelectPrinterFragment extends Fragment {
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+ if (!((DestinationAdapter) mListView.getAdapter()).isActionable(position)) {
+ return;
+ }
PrinterInfo printer = (PrinterInfo) mListView.getAdapter().getItem(position);
Activity activity = getActivity();
if (activity instanceof OnPrinterSelectedListener) {
@@ -138,6 +146,8 @@ public final class SelectPrinterFragment extends Fragment {
}
});
+ registerForContextMenu(mListView);
+
return content;
}
@@ -185,6 +195,62 @@ public final class SelectPrinterFragment extends Fragment {
}
@Override
+ public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo) {
+ if (view == mListView) {
+ final int position = ((AdapterContextMenuInfo) menuInfo).position;
+ PrinterInfo printer = (PrinterInfo) mListView.getAdapter().getItem(position);
+
+ menu.setHeaderTitle(printer.getName());
+
+ // Add the select menu item if applicable.
+ if (printer.getStatus() != PrinterInfo.STATUS_UNAVAILABLE) {
+ MenuItem selectItem = menu.add(Menu.NONE, R.string.print_select_printer,
+ Menu.NONE, R.string.print_select_printer);
+ Intent intent = new Intent();
+ intent.putExtra(EXTRA_PRINTER_ID, printer.getId());
+ selectItem.setIntent(intent);
+ }
+
+ // Add the forget menu item if applicable.
+ FusedPrintersProvider provider = (FusedPrintersProvider) (Loader<?>)
+ getLoaderManager().getLoader(LOADER_ID_PRINTERS_LOADER);
+ if (provider.isFavoritePrinter(printer.getId())) {
+ MenuItem forgetItem = menu.add(Menu.NONE, R.string.print_forget_printer,
+ Menu.NONE, R.string.print_forget_printer);
+ Intent intent = new Intent();
+ intent.putExtra(EXTRA_PRINTER_ID, printer.getId());
+ forgetItem.setIntent(intent);
+ }
+ }
+ }
+
+ @Override
+ public boolean onContextItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case R.string.print_select_printer: {
+ PrinterId printerId = (PrinterId) item.getIntent().getParcelableExtra(
+ EXTRA_PRINTER_ID);
+ Activity activity = getActivity();
+ if (activity instanceof OnPrinterSelectedListener) {
+ ((OnPrinterSelectedListener) activity).onPrinterSelected(printerId);
+ } else {
+ throw new IllegalStateException("the host activity must implement"
+ + " OnPrinterSelectedListener");
+ }
+ } return true;
+
+ case R.string.print_forget_printer: {
+ PrinterId printerId = (PrinterId) item.getIntent().getParcelableExtra(
+ EXTRA_PRINTER_ID);
+ FusedPrintersProvider provider = (FusedPrintersProvider) (Loader<?>)
+ getLoaderManager().getLoader(LOADER_ID_PRINTERS_LOADER);
+ provider.forgetFavoritePrinter(printerId);
+ } return true;
+ }
+ return false;
+ }
+
+ @Override
public void onResume() {
updateAddPrintersAdapter();
getActivity().invalidateOptionsMenu();
@@ -464,7 +530,7 @@ public final class SelectPrinterFragment extends Fragment {
R.layout.printer_list_item, parent, false);
}
- convertView.setEnabled(isEnabled(position));
+ convertView.setEnabled(isActionable(position));
CharSequence title = null;
CharSequence subtitle = null;
@@ -506,8 +572,7 @@ public final class SelectPrinterFragment extends Fragment {
return convertView;
}
- @Override
- public boolean isEnabled(int position) {
+ public boolean isActionable(int position) {
PrinterInfo printer = (PrinterInfo) getItem(position);
return printer.getStatus() != PrinterInfo.STATUS_UNAVAILABLE;
}