Home | History | Annotate | Download | only in util
      1 /*
      2  * Copyright (C) 2013 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.annotation.NonNull;
     20 import android.content.Context;
     21 import android.content.pm.ActivityInfo;
     22 import android.content.res.Configuration;
     23 import android.print.PrintAttributes.MediaSize;
     24 
     25 import com.android.printspooler.R;
     26 
     27 import java.util.Comparator;
     28 import java.util.HashMap;
     29 import java.util.Map;
     30 
     31 /**
     32  * Utility functions and classes for dealing with media sizes.
     33  */
     34 public final class MediaSizeUtils {
     35 
     36     private static Map<MediaSize, Integer> sMediaSizeToStandardMap;
     37 
     38     /** The media size standard for all media sizes no standard is defined for */
     39     private static int sMediaSizeStandardIso;
     40 
     41     private MediaSizeUtils() {
     42         /* do nothing - hide constructor */
     43     }
     44 
     45     /**
     46      * Gets the default media size for the current locale.
     47      *
     48      * @param context Context for accessing resources.
     49      * @return The default media size.
     50      */
     51     public static MediaSize getDefault(Context context) {
     52         String mediaSizeId = context.getString(R.string.mediasize_default);
     53         return MediaSize.getStandardMediaSizeById(mediaSizeId);
     54     }
     55 
     56     /**
     57      * Get the standard the {@link MediaSize} belongs to.
     58      *
     59      * @param context   The context of the caller
     60      * @param mediaSize The {@link MediaSize} to be resolved
     61      *
     62      * @return The standard the {@link MediaSize} belongs to
     63      */
     64     private static int getStandardForMediaSize(Context context, MediaSize mediaSize) {
     65         if (sMediaSizeToStandardMap == null) {
     66             sMediaSizeStandardIso = Integer.parseInt(context.getString(
     67                     R.string.mediasize_standard_iso));
     68 
     69             sMediaSizeToStandardMap = new HashMap<>();
     70             String[] mediaSizeToStandardMapValues = context.getResources()
     71                     .getStringArray(R.array.mediasize_to_standard_map);
     72             final int mediaSizeToStandardCount = mediaSizeToStandardMapValues.length;
     73             for (int i = 0; i < mediaSizeToStandardCount; i += 2) {
     74                 String mediaSizeId = mediaSizeToStandardMapValues[i];
     75                 MediaSize key = MediaSize.getStandardMediaSizeById(mediaSizeId);
     76                 int value = Integer.parseInt(mediaSizeToStandardMapValues[i + 1]);
     77                 sMediaSizeToStandardMap.put(key, value);
     78             }
     79         }
     80         Integer standard = sMediaSizeToStandardMap.get(mediaSize);
     81         return (standard != null) ? standard : sMediaSizeStandardIso;
     82     }
     83 
     84     /**
     85      * Comparator for ordering standard media sizes. The ones for the current
     86      * standard go to the top and the ones for the other standards follow grouped
     87      * by standard. Media sizes of the same standard are ordered alphabetically.
     88      */
     89     public static final class MediaSizeComparator implements Comparator<MediaSize> {
     90         private final Context mContext;
     91 
     92         /** Current configuration */
     93         private Configuration mCurrentConfig;
     94 
     95         /** The standard to use for the current locale */
     96         private int mCurrentStandard;
     97 
     98         /** Mapping from media size to label */
     99         private final @NonNull Map<MediaSize, String> mMediaSizeToLabel;
    100 
    101         public MediaSizeComparator(Context context) {
    102             mContext = context;
    103             mMediaSizeToLabel = new HashMap<>();
    104             mCurrentStandard = Integer.parseInt(mContext.getString(R.string.mediasize_standard));
    105         }
    106 
    107         /**
    108          * Handle a configuration change by reloading all resources.
    109          *
    110          * @param newConfig The new configuration that will be applied.
    111          */
    112         public void onConfigurationChanged(@NonNull Configuration newConfig) {
    113             if (mCurrentConfig == null ||
    114                     (newConfig.diff(mCurrentConfig) & ActivityInfo.CONFIG_LOCALE) != 0) {
    115                 mCurrentStandard = Integer
    116                         .parseInt(mContext.getString(R.string.mediasize_standard));
    117                 mMediaSizeToLabel.clear();
    118 
    119                 mCurrentConfig = newConfig;
    120             }
    121         }
    122 
    123         /**
    124          * Get the label for a {@link MediaSize}.
    125          *
    126          * @param context   The context the label should be loaded for
    127          * @param mediaSize The {@link MediaSize} to resolve
    128          *
    129          * @return The label for the media size
    130          */
    131         public @NonNull String getLabel(@NonNull Context context, @NonNull MediaSize mediaSize) {
    132             String label = mMediaSizeToLabel.get(mediaSize);
    133 
    134             if (label == null) {
    135                 label = mediaSize.getLabel(context.getPackageManager());
    136                 mMediaSizeToLabel.put(mediaSize, label);
    137             }
    138 
    139             return label;
    140         }
    141 
    142         @Override
    143         public int compare(MediaSize lhs, MediaSize rhs) {
    144             int lhsStandard = getStandardForMediaSize(mContext, lhs);
    145             int rhsStandard = getStandardForMediaSize(mContext, rhs);
    146 
    147             // The current standard always wins.
    148             if (lhsStandard == mCurrentStandard) {
    149                 if (rhsStandard != mCurrentStandard) {
    150                     return -1;
    151                 }
    152             } else if (rhsStandard == mCurrentStandard) {
    153                 return 1;
    154             }
    155 
    156             if (lhsStandard != rhsStandard) {
    157                 // Different standards - use the standard ordering.
    158                 return Integer.valueOf(lhsStandard).compareTo(rhsStandard);
    159             } else {
    160                 // Same standard - sort alphabetically by label.
    161                 return getLabel(mContext, lhs).compareTo(getLabel(mContext, rhs));
    162             }
    163         }
    164     }
    165 }
    166