Home | History | Annotate | Download | only in util
      1 /*
      2  * Copyright (C) 2015 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.printspooler.util;
     18 
     19 import android.content.ComponentName;
     20 import android.content.Context;
     21 import android.content.SharedPreferences;
     22 import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
     23 import android.printservice.PrintService;
     24 import android.util.ArraySet;
     25 
     26 import java.util.List;
     27 import java.util.Set;
     28 
     29 /**
     30  * Manage approved print services. These services are stored in the shared preferences.
     31  */
     32 public class ApprovedPrintServices {
     33     /**
     34      * Used for locking accesses to the approved services.
     35      */
     36     static final public Object sLock = new Object();
     37 
     38     private static final String APPROVED_SERVICES_PREFERENCE = "PRINT_SPOOLER_APPROVED_SERVICES";
     39     private final SharedPreferences mPreferences;
     40 
     41     /**
     42      * Create a new {@link ApprovedPrintServices}
     43      *
     44      * @param owner The {@link Context} using this object.
     45      */
     46     public ApprovedPrintServices(Context owner) {
     47         mPreferences = owner.getSharedPreferences(APPROVED_SERVICES_PREFERENCE,
     48                 Context.MODE_PRIVATE);
     49     }
     50 
     51     /**
     52      * Get {@link Set} of approved services.
     53      *
     54      * @return A {@link Set} containing all currently approved services.
     55      */
     56     public Set<String> getApprovedServices() {
     57         return mPreferences.getStringSet(APPROVED_SERVICES_PREFERENCE, null);
     58     }
     59 
     60     /**
     61      * Check if a {@link PrintService} is approved.
     62      *
     63      * This function does not acquire the {@link #sLock}.
     64      *
     65      * @param service The {@link ComponentName} of the {@link PrintService} that might be approved
     66      * @return true iff the service is currently approved
     67      */
     68     public boolean isApprovedService(ComponentName service) {
     69         final Set<String> approvedServices = getApprovedServices();
     70 
     71         if (approvedServices != null) {
     72             final String flattenedString = service.flattenToShortString();
     73 
     74             for (String approvedService : approvedServices) {
     75                 if (approvedService.equals(flattenedString)) {
     76                     return true;
     77                 }
     78             }
     79         }
     80 
     81         return false;
     82     }
     83 
     84     /**
     85      * Add a {@link PrintService} to the list of approved print services.
     86      *
     87      * @param serviceToAdd The {@link ComponentName} of the {@link PrintService} to be approved.
     88      */
     89     public void addApprovedService(ComponentName serviceToAdd) {
     90         synchronized (sLock) {
     91             Set<String> oldApprovedServices =
     92                     mPreferences.getStringSet(APPROVED_SERVICES_PREFERENCE, null);
     93 
     94             Set<String> newApprovedServices;
     95             if (oldApprovedServices == null) {
     96                 newApprovedServices = new ArraySet<String>(1);
     97             } else {
     98                 // Copy approved services.
     99                 newApprovedServices = new ArraySet<String>(oldApprovedServices);
    100             }
    101             newApprovedServices.add(serviceToAdd.flattenToShortString());
    102 
    103             SharedPreferences.Editor editor = mPreferences.edit();
    104             editor.putStringSet(APPROVED_SERVICES_PREFERENCE, newApprovedServices);
    105             editor.apply();
    106         }
    107     }
    108 
    109     /**
    110      * Add a {@link OnSharedPreferenceChangeListener} that listens for changes to the approved
    111      * services. Should only be called while holding {@link #sLock} to synchronize against
    112      * {@link #addApprovedService}.
    113      *
    114      * @param listener {@link OnSharedPreferenceChangeListener} to register
    115      */
    116     public void registerChangeListenerLocked(OnSharedPreferenceChangeListener listener) {
    117         mPreferences.registerOnSharedPreferenceChangeListener(listener);
    118     }
    119 
    120     /**
    121      * Unregister a listener registered in {@link #registerChangeListenerLocked}.
    122      *
    123      * @param listener {@link OnSharedPreferenceChangeListener} to unregister
    124      */
    125     public void unregisterChangeListener(OnSharedPreferenceChangeListener listener) {
    126         mPreferences.unregisterOnSharedPreferenceChangeListener(listener);
    127     }
    128 
    129     /**
    130      * Remove all approved {@link PrintService print services} that are not in the given set.
    131      *
    132      * @param serviceNamesToKeep The {@link ComponentName names } of the services to keep
    133      */
    134     public void pruneApprovedServices(List<ComponentName> serviceNamesToKeep) {
    135         synchronized (sLock) {
    136             Set<String> approvedServices = getApprovedServices();
    137 
    138             if (approvedServices == null) {
    139                 return;
    140             }
    141 
    142             Set<String> newApprovedServices = new ArraySet<>(approvedServices.size());
    143 
    144             final int numServiceNamesToKeep = serviceNamesToKeep.size();
    145             for(int i = 0; i < numServiceNamesToKeep; i++) {
    146                 String serviceToKeep = serviceNamesToKeep.get(i).flattenToShortString();
    147                 if (approvedServices.contains(serviceToKeep)) {
    148                     newApprovedServices.add(serviceToKeep);
    149                 }
    150             }
    151 
    152             if (approvedServices.size() != newApprovedServices.size()) {
    153                 SharedPreferences.Editor editor = mPreferences.edit();
    154 
    155                 editor.putStringSet(APPROVED_SERVICES_PREFERENCE, newApprovedServices);
    156                 editor.apply();
    157             }
    158         }
    159     }
    160 }
    161