• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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