1 /* 2 * Copyright (C) 2019 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.bluetooth.avrcpcontroller; 18 19 import android.util.SparseArray; 20 21 import java.util.HashMap; 22 23 /** 24 * Represents an encoding method in which a BIP image is available. 25 * 26 * <p>The encodings supported by this profile include: - JPEG - GIF - WBMP - PNG - JPEG2000 - BMP - 27 * USR-xxx 28 * 29 * <p>The tag USR-xxx is used to represent proprietary encodings. The tag shall begin with the 30 * string “USR-” but the implementer assigns the characters of the second half of the string. This 31 * tag can be used by a manufacturer to enable its devices to exchange images under a proprietary 32 * encoding. 33 * 34 * <p>Example proprietary encoding: 35 * 36 * <p>- USR-NOKIA-FORMAT1 37 */ 38 public class BipEncoding { 39 public static final int JPEG = 0; 40 public static final int PNG = 1; 41 public static final int BMP = 2; 42 public static final int GIF = 3; 43 public static final int JPEG2000 = 4; 44 public static final int WBMP = 5; 45 public static final int USR_XXX = 6; 46 public static final int UNKNOWN = 7; // i.e 'not assigned' or 'not assigned anything valid' 47 48 private static final HashMap sEncodingNamesToIds = new HashMap<String, Integer>(); 49 50 static { 51 sEncodingNamesToIds.put("JPEG", JPEG); 52 sEncodingNamesToIds.put("GIF", GIF); 53 sEncodingNamesToIds.put("WBMP", WBMP); 54 sEncodingNamesToIds.put("PNG", PNG); 55 sEncodingNamesToIds.put("JPEG2000", JPEG2000); 56 sEncodingNamesToIds.put("BMP", BMP); 57 } 58 59 private static final SparseArray sIdsToEncodingNames = new SparseArray<String>(); 60 61 static { sIdsToEncodingNames.put(JPEG, "JPEG")62 sIdsToEncodingNames.put(JPEG, "JPEG"); sIdsToEncodingNames.put(GIF, "GIF")63 sIdsToEncodingNames.put(GIF, "GIF"); sIdsToEncodingNames.put(WBMP, "WBMP")64 sIdsToEncodingNames.put(WBMP, "WBMP"); sIdsToEncodingNames.put(PNG, "PNG")65 sIdsToEncodingNames.put(PNG, "PNG"); sIdsToEncodingNames.put(JPEG2000, "JPEG2000")66 sIdsToEncodingNames.put(JPEG2000, "JPEG2000"); sIdsToEncodingNames.put(BMP, "BMP")67 sIdsToEncodingNames.put(BMP, "BMP"); sIdsToEncodingNames.put(UNKNOWN, "UNKNOWN")68 sIdsToEncodingNames.put(UNKNOWN, "UNKNOWN"); 69 } 70 71 /** The integer ID of the type that this encoding is */ 72 private final int mType; 73 74 /** If an encoding is type USR_XXX then it has an extension that defines the encoding */ 75 private final String mProprietaryEncodingId; 76 77 /** 78 * Create an encoding object based on a AVRCP specification defined string of the encoding name 79 * 80 * @param encoding The encoding name 81 */ BipEncoding(String encoding)82 public BipEncoding(String encoding) { 83 if (encoding == null) { 84 throw new ParseException("Encoding input invalid"); 85 } 86 encoding = encoding.trim(); 87 mType = determineEncoding(encoding.toUpperCase()); 88 89 String proprietaryEncodingId = null; 90 if (mType == USR_XXX) { 91 proprietaryEncodingId = encoding.substring(4).toUpperCase(); 92 } 93 mProprietaryEncodingId = proprietaryEncodingId; 94 95 // If we don't have a type by now, we've failed to parse the encoding 96 if (mType == UNKNOWN) { 97 throw new ParseException("Failed to determine type of '" + encoding + "'"); 98 } 99 } 100 101 /** 102 * Create an encoding object based on one of the constants for the available formats 103 * 104 * @param encoding A constant representing an available encoding 105 * @param proprietaryId A string representing the Id of a propreitary encoding. Only used if the 106 * encoding type is BipEncoding.USR_XXX 107 */ BipEncoding(int encoding, String proprietaryId)108 public BipEncoding(int encoding, String proprietaryId) { 109 if (encoding < 0 || encoding > USR_XXX) { 110 throw new IllegalArgumentException("Received invalid encoding type '" + encoding + "'"); 111 } 112 mType = encoding; 113 114 String proprietaryEncodingId = null; 115 if (mType == USR_XXX) { 116 if (proprietaryId == null) { 117 throw new IllegalArgumentException( 118 "Received invalid user defined encoding id '" + proprietaryId + "'"); 119 } 120 proprietaryEncodingId = proprietaryId.toUpperCase(); 121 } 122 mProprietaryEncodingId = proprietaryEncodingId; 123 } 124 BipEncoding(int encoding)125 public BipEncoding(int encoding) { 126 this(encoding, null); 127 } 128 129 /** 130 * Returns the encoding type 131 * 132 * @return Integer type ID of the encoding 133 */ getType()134 public int getType() { 135 return mType; 136 } 137 138 /** 139 * Returns the ID portion of an encoding if it's a proprietary encoding 140 * 141 * @return String ID of a proprietary encoding, or null if the encoding is not proprietary 142 */ getProprietaryEncodingId()143 public String getProprietaryEncodingId() { 144 return mProprietaryEncodingId; 145 } 146 147 /** 148 * Determines if an encoding is supported by Android's Graphics Framework 149 * 150 * <p>Android's Bitmap/BitmapFactory can handle BMP, GIF, JPEG, PNG, WebP, and HEIF formats. 151 * 152 * @return True if the encoding is supported, False otherwise. 153 */ isAndroidSupported()154 public boolean isAndroidSupported() { 155 return mType == BipEncoding.JPEG 156 || mType == BipEncoding.PNG 157 || mType == BipEncoding.BMP 158 || mType == BipEncoding.GIF; 159 } 160 161 /** Determine the encoding type based on an input string */ determineEncoding(String encoding)162 private static int determineEncoding(String encoding) { 163 Integer type = (Integer) sEncodingNamesToIds.get(encoding); 164 if (type != null) return type.intValue(); 165 if (encoding != null && encoding.length() >= 4 && encoding.substring(0, 4).equals("USR-")) { 166 return USR_XXX; 167 } 168 return UNKNOWN; 169 } 170 171 @Override equals(Object o)172 public boolean equals(Object o) { 173 if (o == this) return true; 174 if (!(o instanceof BipEncoding)) return false; 175 176 BipEncoding e = (BipEncoding) o; 177 return e.getType() == getType() 178 && e.getProprietaryEncodingId() == getProprietaryEncodingId(); 179 } 180 181 @Override toString()182 public String toString() { 183 if (mType == USR_XXX) return "USR-" + mProprietaryEncodingId; 184 String encoding = (String) sIdsToEncodingNames.get(mType); 185 return encoding; 186 } 187 } 188