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

Commit 4033c94b authored by Svetoslav's avatar Svetoslav Committed by Android (Google) Code Review
Browse files

Merge "Add way for the user to forget previously used printers." into klp-dev

parents e19ed435 1c664b6d
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -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>
+95 −14
Original line number Diff line number Diff line
@@ -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);
+1 −0
Original line number Diff line number Diff line
@@ -937,6 +937,7 @@ public class PrintJobConfigActivity extends Activity {
                            mPrintJobId, mCurrentPrinter);

                    if (mCurrentPrinter.getStatus() == PrinterInfo.STATUS_UNAVAILABLE) {
                        mCapabilitiesTimeout.post();
                        updateUi();
                        return;
                    }
+68 −3
Original line number Diff line number Diff line
@@ -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;
    }

@@ -184,6 +194,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();
@@ -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;
        }