Home | History | Annotate | Download | only in discovery
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.bips.discovery;
     18 
     19 import android.net.Uri;
     20 import android.util.JsonReader;
     21 import android.util.JsonWriter;
     22 import android.util.Log;
     23 
     24 import com.android.bips.BuiltInPrintService;
     25 
     26 import java.io.BufferedReader;
     27 import java.io.BufferedWriter;
     28 import java.io.File;
     29 import java.io.FileReader;
     30 import java.io.FileWriter;
     31 import java.io.IOException;
     32 import java.util.ArrayList;
     33 import java.util.Arrays;
     34 import java.util.Collections;
     35 import java.util.List;
     36 
     37 /**
     38  * A {@link Discovery} subclass managing a list of {@link DiscoveredPrinter} objects, persisted
     39  * between application sessions
     40  */
     41 public abstract class SavedDiscovery extends Discovery {
     42     private static final String TAG = SavedDiscovery.class.getSimpleName();
     43     private static final boolean DEBUG = false;
     44 
     45     // manualPrinters for backward-compatibility
     46     private static final List<String> PRINTER_LIST_NAMES = Arrays.asList("printers",
     47             "manualPrinters");
     48 
     49     private final File mCacheFile;
     50     private final List<DiscoveredPrinter> mSavedPrinters;
     51 
     52     SavedDiscovery(BuiltInPrintService printService) {
     53         super(printService);
     54         mCacheFile = new File(printService.getCacheDir(), getClass().getSimpleName() + ".json");
     55         mSavedPrinters = load();
     56     }
     57 
     58     /**
     59      * Add a persisted printer, returning true if a change occurred
     60      */
     61     boolean addSavedPrinter(DiscoveredPrinter printer) {
     62         Uri printerUri = printer.getUri();
     63         DiscoveredPrinter old = find(printerUri);
     64         if (old != null) {
     65             if (printer.equals(old)) {
     66                 return false;
     67             }
     68             mSavedPrinters.remove(old);
     69         }
     70 
     71         mSavedPrinters.add(0, printer);
     72         save();
     73         return true;
     74     }
     75 
     76     /**
     77      * Return a DiscoveredPrinter having the specified URI, or null
     78      */
     79     private DiscoveredPrinter find(Uri printerUri) {
     80         for (DiscoveredPrinter printer : mSavedPrinters) {
     81             if (printer.getUri().equals(printerUri)) {
     82                 return printer;
     83             }
     84         }
     85         return null;
     86     }
     87 
     88     /**
     89      * Remove the first saved printer matching the supplied printer path
     90      */
     91     @Override
     92     public void removeSavedPrinter(Uri printerPath) {
     93         for (DiscoveredPrinter printer : mSavedPrinters) {
     94             if (printer.path.equals(printerPath)) {
     95                 mSavedPrinters.remove(printer);
     96                 save();
     97                 return;
     98             }
     99         }
    100     }
    101 
    102     /**
    103      * Return a non-modifiable list of saved printers
    104      */
    105     @Override
    106     public List<DiscoveredPrinter> getSavedPrinters() {
    107         return Collections.unmodifiableList(mSavedPrinters);
    108     }
    109 
    110     /**
    111      * Load the list from storage, or return an empty list
    112      */
    113     private List<DiscoveredPrinter> load() {
    114         List<DiscoveredPrinter> printers = new ArrayList<>();
    115         if (!mCacheFile.exists()) {
    116             return printers;
    117         }
    118 
    119         try (JsonReader reader = new JsonReader(new BufferedReader(new FileReader(mCacheFile)))) {
    120             reader.beginObject();
    121             while (reader.hasNext()) {
    122                 String itemName = reader.nextName();
    123                 if (PRINTER_LIST_NAMES.contains(itemName)) {
    124                     reader.beginArray();
    125                     while (reader.hasNext()) {
    126                         printers.add(new DiscoveredPrinter(reader));
    127                     }
    128                     reader.endArray();
    129                 }
    130             }
    131             reader.endObject();
    132         } catch (IllegalStateException | IOException ignored) {
    133             Log.w(TAG, "Error while loading from " + mCacheFile, ignored);
    134         }
    135         if (DEBUG) Log.d(TAG, "Loaded size=" + printers.size() + " from " + mCacheFile);
    136         return printers;
    137     }
    138 
    139     /**
    140      * Save the current list to storage
    141      */
    142     private void save() {
    143         if (mCacheFile.exists()) {
    144             mCacheFile.delete();
    145         }
    146 
    147         try (JsonWriter writer = new JsonWriter(new BufferedWriter(new FileWriter(mCacheFile)))) {
    148             writer.beginObject();
    149             writer.name(PRINTER_LIST_NAMES.get(0));
    150             writer.beginArray();
    151             for (DiscoveredPrinter printer : mSavedPrinters) {
    152                 printer.write(writer);
    153             }
    154             writer.endArray();
    155             writer.endObject();
    156         } catch (NullPointerException | IOException e) {
    157             Log.w(TAG, "Error while storing to " + mCacheFile, e);
    158         }
    159     }
    160 }
    161