1 /* 2 * Copyright (C) 2016 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.support.v4.media.session.PlaybackStateCompat; 20 import android.util.Log; 21 import android.util.SparseArray; 22 23 import com.android.internal.annotations.VisibleForTesting; 24 25 import java.util.ArrayList; 26 27 /* 28 * Contains information Player Application Setting extended from BluetootAvrcpPlayerSettings 29 */ 30 class PlayerApplicationSettings { 31 private static final String TAG = "PlayerApplicationSettings"; 32 33 /* 34 * Values for SetPlayerApplicationSettings from AVRCP Spec V1.6 Appendix F. 35 */ 36 static final byte EQUALIZER_STATUS = 0x01; 37 static final byte REPEAT_STATUS = 0x02; 38 static final byte SHUFFLE_STATUS = 0x03; 39 static final byte SCAN_STATUS = 0x04; 40 41 private static final byte JNI_EQUALIZER_STATUS_OFF = 0x01; 42 private static final byte JNI_EQUALIZER_STATUS_ON = 0x02; 43 44 @VisibleForTesting 45 static final byte JNI_REPEAT_STATUS_OFF = 0x01; 46 @VisibleForTesting 47 static final byte JNI_REPEAT_STATUS_SINGLE_TRACK_REPEAT = 0x02; 48 @VisibleForTesting 49 static final byte JNI_REPEAT_STATUS_ALL_TRACK_REPEAT = 0x03; 50 @VisibleForTesting 51 static final byte JNI_REPEAT_STATUS_GROUP_REPEAT = 0x04; 52 53 @VisibleForTesting 54 static final byte JNI_SHUFFLE_STATUS_OFF = 0x01; 55 @VisibleForTesting 56 static final byte JNI_SHUFFLE_STATUS_ALL_TRACK_SHUFFLE = 0x02; 57 @VisibleForTesting 58 static final byte JNI_SHUFFLE_STATUS_GROUP_SHUFFLE = 0x03; 59 60 private static final byte JNI_SCAN_STATUS_OFF = 0x01; 61 private static final byte JNI_SCAN_STATUS_ALL_TRACK_SCAN = 0x02; 62 private static final byte JNI_SCAN_STATUS_GROUP_SCAN = 0x03; 63 64 @VisibleForTesting 65 static final byte JNI_STATUS_INVALID = -1; 66 67 /* 68 * Hash map of current settings. 69 */ 70 private SparseArray<Integer> mSettings = new SparseArray<>(); 71 72 /* 73 * Hash map of supported values, a setting should be supported by the remote in order to enable 74 * in mSettings. 75 */ 76 private SparseArray<ArrayList<Integer>> mSupportedValues = 77 new SparseArray<ArrayList<Integer>>(); 78 79 /* Convert from JNI array to Java classes. */ makeSupportedSettings(byte[] btAvrcpAttributeList)80 static PlayerApplicationSettings makeSupportedSettings(byte[] btAvrcpAttributeList) { 81 PlayerApplicationSettings newObj = new PlayerApplicationSettings(); 82 try { 83 for (int i = 0; i < btAvrcpAttributeList.length; ) { 84 byte attrId = btAvrcpAttributeList[i++]; 85 byte numSupportedVals = btAvrcpAttributeList[i++]; 86 ArrayList<Integer> supportedValues = new ArrayList<Integer>(); 87 88 for (int j = 0; j < numSupportedVals; j++) { 89 // Yes, keep using i for array indexing. 90 supportedValues.add( 91 mapAttribIdValtoAvrcpPlayerSetting(attrId, btAvrcpAttributeList[i++])); 92 } 93 newObj.mSupportedValues.put(attrId, supportedValues); 94 } 95 } catch (ArrayIndexOutOfBoundsException exception) { 96 Log.e(TAG, "makeSupportedSettings attributeList index error."); 97 } 98 return newObj; 99 } 100 makeSettings(byte[] btAvrcpAttributeList)101 static PlayerApplicationSettings makeSettings(byte[] btAvrcpAttributeList) { 102 PlayerApplicationSettings newObj = new PlayerApplicationSettings(); 103 try { 104 for (int i = 0; i < btAvrcpAttributeList.length; ) { 105 byte attrId = btAvrcpAttributeList[i++]; 106 107 newObj.mSettings.put(attrId, 108 mapAttribIdValtoAvrcpPlayerSetting(attrId, btAvrcpAttributeList[i++])); 109 } 110 } catch (ArrayIndexOutOfBoundsException exception) { 111 Log.e(TAG, "makeSettings JNI_ATTRIButeList index error."); 112 } 113 return newObj; 114 } 115 setSupport(PlayerApplicationSettings updates)116 public void setSupport(PlayerApplicationSettings updates) { 117 mSettings = updates.mSettings; 118 mSupportedValues = updates.mSupportedValues; 119 } 120 supportsSetting(int settingType, int settingValue)121 public boolean supportsSetting(int settingType, int settingValue) { 122 if (null == mSupportedValues.get(settingType)) return false; 123 return mSupportedValues.valueAt(settingType).contains(settingValue); 124 } 125 supportsSetting(int settingType)126 public boolean supportsSetting(int settingType) { 127 return (null != mSupportedValues.get(settingType)); 128 } 129 getSetting(int settingType)130 public int getSetting(int settingType) { 131 if (null == mSettings.get(settingType)) return -1; 132 return mSettings.get(settingType); 133 } 134 135 // Convert a native Attribute Id/Value pair into the AVRCP equivalent value. 136 @VisibleForTesting mapAttribIdValtoAvrcpPlayerSetting(byte attribId, byte attribVal)137 static int mapAttribIdValtoAvrcpPlayerSetting(byte attribId, byte attribVal) { 138 if (attribId == REPEAT_STATUS) { 139 switch (attribVal) { 140 case JNI_REPEAT_STATUS_ALL_TRACK_REPEAT: 141 return PlaybackStateCompat.REPEAT_MODE_ALL; 142 case JNI_REPEAT_STATUS_GROUP_REPEAT: 143 return PlaybackStateCompat.REPEAT_MODE_GROUP; 144 case JNI_REPEAT_STATUS_OFF: 145 return PlaybackStateCompat.REPEAT_MODE_NONE; 146 case JNI_REPEAT_STATUS_SINGLE_TRACK_REPEAT: 147 return PlaybackStateCompat.REPEAT_MODE_ONE; 148 } 149 } else if (attribId == SHUFFLE_STATUS) { 150 switch (attribVal) { 151 case JNI_SHUFFLE_STATUS_ALL_TRACK_SHUFFLE: 152 return PlaybackStateCompat.SHUFFLE_MODE_ALL; 153 case JNI_SHUFFLE_STATUS_GROUP_SHUFFLE: 154 return PlaybackStateCompat.SHUFFLE_MODE_GROUP; 155 case JNI_SHUFFLE_STATUS_OFF: 156 return PlaybackStateCompat.SHUFFLE_MODE_NONE; 157 } 158 } 159 return JNI_STATUS_INVALID; 160 } 161 162 // Convert an AVRCP Setting/Value pair into the native equivalent value; mapAvrcpPlayerSettingstoBTattribVal(int mSetting, int mSettingVal)163 static byte mapAvrcpPlayerSettingstoBTattribVal(int mSetting, int mSettingVal) { 164 if (mSetting == REPEAT_STATUS) { 165 switch (mSettingVal) { 166 case PlaybackStateCompat.REPEAT_MODE_NONE: 167 return JNI_REPEAT_STATUS_OFF; 168 case PlaybackStateCompat.REPEAT_MODE_ONE: 169 return JNI_REPEAT_STATUS_SINGLE_TRACK_REPEAT; 170 case PlaybackStateCompat.REPEAT_MODE_ALL: 171 return JNI_REPEAT_STATUS_ALL_TRACK_REPEAT; 172 case PlaybackStateCompat.REPEAT_MODE_GROUP: 173 return JNI_REPEAT_STATUS_GROUP_REPEAT; 174 } 175 } else if (mSetting == SHUFFLE_STATUS) { 176 switch (mSettingVal) { 177 case PlaybackStateCompat.SHUFFLE_MODE_NONE: 178 return JNI_SHUFFLE_STATUS_OFF; 179 case PlaybackStateCompat.SHUFFLE_MODE_ALL: 180 return JNI_SHUFFLE_STATUS_ALL_TRACK_SHUFFLE; 181 case PlaybackStateCompat.SHUFFLE_MODE_GROUP: 182 return JNI_SHUFFLE_STATUS_GROUP_SHUFFLE; 183 } 184 } 185 return JNI_STATUS_INVALID; 186 } 187 } 188