13bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy/* 23bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy * Copyright (C) 2013 The Android Open Source Project 33bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy * 43bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy * Licensed under the Apache License, Version 2.0 (the "License"); 53bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy * you may not use this file except in compliance with the License. 63bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy * You may obtain a copy of the License at 73bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy * 83bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy * http://www.apache.org/licenses/LICENSE-2.0 93bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy * 103bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy * Unless required by applicable law or agreed to in writing, software 113bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy * distributed under the License is distributed on an "AS IS" BASIS, 123bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy * See the License for the specific language governing permissions and 143bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy * limitations under the License. 153bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy */ 163bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy 173bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guypackage com.android.printspooler.util; 183bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy 193bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guyimport android.annotation.NonNull; 203bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guyimport android.content.Context; 213bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guyimport android.content.pm.ActivityInfo; 223bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guyimport android.content.res.Configuration; 233bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guyimport android.print.PrintAttributes.MediaSize; 243bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy 253bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guyimport com.android.printspooler.R; 263bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy 273bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guyimport java.util.Comparator; 283bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guyimport java.util.HashMap; 293bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guyimport java.util.Map; 303bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy 313bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy/** 323bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy * Utility functions and classes for dealing with media sizes. 333bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy */ 343bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guypublic final class MediaSizeUtils { 353bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy 363bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy private static Map<MediaSize, Integer> sMediaSizeToStandardMap; 373bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy 383bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy /** The media size standard for all media sizes no standard is defined for */ 393bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy private static int sMediaSizeStandardIso; 403bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy 413bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy private MediaSizeUtils() { 428d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy /* do nothing - hide constructor */ 433bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy } 443bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy 453bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy /** 463bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy * Gets the default media size for the current locale. 473bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy * 483bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy * @param context Context for accessing resources. 493bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy * @return The default media size. 503bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy */ 513bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy public static MediaSize getDefault(Context context) { 523bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy String mediaSizeId = context.getString(R.string.mediasize_default); 533bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy return MediaSize.getStandardMediaSizeById(mediaSizeId); 543bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy } 553bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy 563bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy /** 573bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy * Get the standard the {@link MediaSize} belongs to. 583bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy * 593bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy * @param context The context of the caller 603bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy * @param mediaSize The {@link MediaSize} to be resolved 613bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy * 623bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy * @return The standard the {@link MediaSize} belongs to 633bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy */ 643bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy private static int getStandardForMediaSize(Context context, MediaSize mediaSize) { 653bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy if (sMediaSizeToStandardMap == null) { 663bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy sMediaSizeStandardIso = Integer.parseInt(context.getString( 673bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy R.string.mediasize_standard_iso)); 683bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy 693bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy sMediaSizeToStandardMap = new HashMap<>(); 703bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy String[] mediaSizeToStandardMapValues = context.getResources() 713bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy .getStringArray(R.array.mediasize_to_standard_map); 723bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy final int mediaSizeToStandardCount = mediaSizeToStandardMapValues.length; 733bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy for (int i = 0; i < mediaSizeToStandardCount; i += 2) { 743bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy String mediaSizeId = mediaSizeToStandardMapValues[i]; 753bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy MediaSize key = MediaSize.getStandardMediaSizeById(mediaSizeId); 763bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy int value = Integer.parseInt(mediaSizeToStandardMapValues[i + 1]); 773bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy sMediaSizeToStandardMap.put(key, value); 783bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy } 793bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy } 803bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy Integer standard = sMediaSizeToStandardMap.get(mediaSize); 813bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy return (standard != null) ? standard : sMediaSizeStandardIso; 823bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy } 833bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy 843bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy /** 853bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy * Comparator for ordering standard media sizes. The ones for the current 863bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy * standard go to the top and the ones for the other standards follow grouped 873bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy * by standard. Media sizes of the same standard are ordered alphabetically. 883bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy */ 893bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy public static final class MediaSizeComparator implements Comparator<MediaSize> { 903bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy private final Context mContext; 913bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy 923bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy /** Current configuration */ 933bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy private Configuration mCurrentConfig; 943bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy 953bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy /** The standard to use for the current locale */ 963bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy private int mCurrentStandard; 973bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy 983bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy /** Mapping from media size to label */ 993bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy private final @NonNull Map<MediaSize, String> mMediaSizeToLabel; 1003bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy 1013bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy public MediaSizeComparator(Context context) { 1023bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy mContext = context; 1033bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy mMediaSizeToLabel = new HashMap<>(); 1043bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy mCurrentStandard = Integer.parseInt(mContext.getString(R.string.mediasize_standard)); 1053bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy } 1063bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy 1073bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy /** 1083bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy * Handle a configuration change by reloading all resources. 1093bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy * 1103bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy * @param newConfig The new configuration that will be applied. 1113bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy */ 1123bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy public void onConfigurationChanged(@NonNull Configuration newConfig) { 1133bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy if (mCurrentConfig == null || 1143bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy (newConfig.diff(mCurrentConfig) & ActivityInfo.CONFIG_LOCALE) != 0) { 1153bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy mCurrentStandard = Integer 1163bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy .parseInt(mContext.getString(R.string.mediasize_standard)); 1173bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy mMediaSizeToLabel.clear(); 1183bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy 1193bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy mCurrentConfig = newConfig; 1203bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy } 1213bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy } 1223bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy 1233bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy /** 1243bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy * Get the label for a {@link MediaSize}. 1253bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy * 1263bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy * @param context The context the label should be loaded for 1273bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy * @param mediaSize The {@link MediaSize} to resolve 1283bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy * 1293bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy * @return The label for the media size 1303bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy */ 1313bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy public @NonNull String getLabel(@NonNull Context context, @NonNull MediaSize mediaSize) { 1323bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy String label = mMediaSizeToLabel.get(mediaSize); 1333bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy 1343bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy if (label == null) { 1353bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy label = mediaSize.getLabel(context.getPackageManager()); 1363bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy mMediaSizeToLabel.put(mediaSize, label); 1373bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy } 1383bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy 1393bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy return label; 1403bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy } 1413bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy 1423bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy @Override 1433bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy public int compare(MediaSize lhs, MediaSize rhs) { 1443bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy int lhsStandard = getStandardForMediaSize(mContext, lhs); 1453bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy int rhsStandard = getStandardForMediaSize(mContext, rhs); 1463bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy 1473bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy // The current standard always wins. 1483bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy if (lhsStandard == mCurrentStandard) { 1493bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy if (rhsStandard != mCurrentStandard) { 1503bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy return -1; 1513bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy } 1523bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy } else if (rhsStandard == mCurrentStandard) { 1533bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy return 1; 1543bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy } 1553bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy 1563bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy if (lhsStandard != rhsStandard) { 1578d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy // Different standards - use the standard ordering. 1588d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy return Integer.valueOf(lhsStandard).compareTo(rhsStandard); 1598d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy } else { 1608d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy // Same standard - sort alphabetically by label. 1618d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy return getLabel(mContext, lhs).compareTo(getLabel(mContext, rhs)); 1628d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy } 1638d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy } 1648d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy } 1658d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy} 1668d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy