1 package com.mobileer.audio_device;
2 /*
3  * Copyright 2017 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 import android.annotation.TargetApi;
19 import android.content.Context;
20 import android.content.res.Resources.Theme;
21 import android.media.AudioDeviceCallback;
22 import android.media.AudioDeviceInfo;
23 import android.media.AudioManager;
24 import android.util.AttributeSet;
25 import android.widget.Spinner;
26 
27 import com.mobileer.oboetester.R;
28 
29 import java.util.List;
30 
31 public class AudioDeviceSpinner extends Spinner {
32 
33     private static final int AUTO_SELECT_DEVICE_ID = 0;
34     private static final String TAG = AudioDeviceSpinner.class.getName();
35     private int mDirectionType;
36     private AudioDeviceAdapter mDeviceAdapter;
37     private AudioManager mAudioManager;
38     private Context mContext;
39 
AudioDeviceSpinner(Context context)40     public AudioDeviceSpinner(Context context){
41         super(context);
42         setup(context);
43     }
44 
AudioDeviceSpinner(Context context, int mode)45     public AudioDeviceSpinner(Context context, int mode){
46         super(context, mode);
47         setup(context);
48     }
49 
AudioDeviceSpinner(Context context, AttributeSet attrs)50     public AudioDeviceSpinner(Context context, AttributeSet attrs){
51         super(context, attrs);
52         setup(context);
53     }
54 
AudioDeviceSpinner(Context context, AttributeSet attrs, int defStyleAttr)55     public AudioDeviceSpinner(Context context, AttributeSet attrs, int defStyleAttr){
56         super(context, attrs, defStyleAttr);
57         setup(context);
58     }
59 
AudioDeviceSpinner(Context context, AttributeSet attrs, int defStyleAttr, int mode)60     public AudioDeviceSpinner(Context context, AttributeSet attrs, int defStyleAttr, int mode){
61         super(context, attrs, defStyleAttr, mode);
62         setup(context);
63     }
64 
AudioDeviceSpinner(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes, int mode)65     public AudioDeviceSpinner(Context context, AttributeSet attrs, int defStyleAttr,
66                               int defStyleRes, int mode){
67         super(context, attrs, defStyleAttr, defStyleRes, mode);
68         setup(context);
69     }
70 
AudioDeviceSpinner(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes, int mode, Theme popupTheme)71     public AudioDeviceSpinner(Context context, AttributeSet attrs, int defStyleAttr,
72                               int defStyleRes, int mode, Theme popupTheme){
73         super(context, attrs, defStyleAttr, defStyleRes, mode, popupTheme);
74         setup(context);
75     }
76 
setup(Context context)77     private void setup(Context context){
78         mContext = context;
79 
80         mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
81 
82         mDeviceAdapter = new AudioDeviceAdapter(context);
83         setAdapter(mDeviceAdapter);
84 
85         // Add a default entry to the list and select it
86         mDeviceAdapter.add(new AudioDeviceListEntry(AUTO_SELECT_DEVICE_ID,
87                 mContext.getString(R.string.auto_select)));
88         setSelection(0);
89 
90     }
91 
92     @TargetApi(23)
setDirectionType(int directionType)93     public void setDirectionType(int directionType){
94         this.mDirectionType = directionType;
95         setupAudioDeviceCallback();
96     }
97 
98     @TargetApi(23)
setupAudioDeviceCallback()99     private void setupAudioDeviceCallback(){
100 
101         // Note that we will immediately receive a call to onDevicesAdded with the list of
102         // devices which are currently connected.
103         mAudioManager.registerAudioDeviceCallback(new AudioDeviceCallback() {
104             @Override
105             public void onAudioDevicesAdded(AudioDeviceInfo[] addedDevices) {
106                 List<AudioDeviceListEntry> deviceList =
107                         AudioDeviceListEntry.createListFrom(addedDevices, mDirectionType);
108                 if (deviceList.size() > 0){
109                     // Prevent duplicate entries caused by b/80138804
110                     for (AudioDeviceListEntry entry : deviceList){
111                         mDeviceAdapter.remove(entry);
112                     }
113                     mDeviceAdapter.addAll(deviceList);
114                 }
115             }
116 
117             public void onAudioDevicesRemoved(AudioDeviceInfo[] removedDevices) {
118                 List<AudioDeviceListEntry> deviceList =
119                         AudioDeviceListEntry.createListFrom(removedDevices, mDirectionType);
120                 for (AudioDeviceListEntry entry : deviceList){
121                     mDeviceAdapter.remove(entry);
122                 }
123                 setSelection(0);
124             }
125         }, null);
126     }
127 }
128