1 /*
2  * Copyright 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.google.sample.oboe.manualtest;
18 
19 import android.annotation.TargetApi;
20 import android.app.Activity;
21 import android.content.Context;
22 import android.content.pm.PackageManager;
23 import android.media.AudioDeviceCallback;
24 import android.media.AudioDeviceInfo;
25 import android.media.AudioManager;
26 import android.media.MicrophoneInfo;
27 import android.os.Bundle;
28 import android.text.method.ScrollingMovementMethod;
29 import android.widget.TextView;
30 
31 import com.google.sample.audio_device.AudioDeviceInfoConverter;
32 
33 import java.io.IOException;
34 import java.util.Collection;
35 import java.util.HashMap;
36 import java.util.List;
37 
38 /**
39  * Guide the user through a series of tests plugging in and unplugging a headset.
40  * Print a summary at the end of any failures.
41  */
42 public class DeviceReportActivity extends Activity {
43 
44     class MyAudioDeviceCallback extends AudioDeviceCallback {
45         private HashMap<Integer, AudioDeviceInfo> mDevices
46                 = new HashMap<Integer, AudioDeviceInfo>();
47 
48         @Override
onAudioDevicesAdded(AudioDeviceInfo[] addedDevices)49         public void onAudioDevicesAdded(AudioDeviceInfo[] addedDevices) {
50             for (AudioDeviceInfo info : addedDevices) {
51                 mDevices.put(info.getId(), info);
52             }
53             reportDeviceInfo(mDevices.values());
54         }
55 
onAudioDevicesRemoved(AudioDeviceInfo[] removedDevices)56         public void onAudioDevicesRemoved(AudioDeviceInfo[] removedDevices) {
57             for (AudioDeviceInfo info : removedDevices) {
58                 mDevices.remove(info.getId());
59             }
60             reportDeviceInfo(mDevices.values());
61         }
62     }
63 
64     MyAudioDeviceCallback mDeviceCallback = new MyAudioDeviceCallback();
65     private TextView      mAutoTextView;
66     private AudioManager  mAudioManager;
67 
68     @Override
onCreate(Bundle savedInstanceState)69     protected void onCreate(Bundle savedInstanceState) {
70         super.onCreate(savedInstanceState);
71         setContentView(R.layout.activity_device_report);
72         mAutoTextView = (TextView) findViewById(R.id.text_log);
73         mAutoTextView.setMovementMethod(new ScrollingMovementMethod());
74 
75         mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
76     }
77 
78     @Override
onStart()79     protected void onStart() {
80         super.onStart();
81         addAudioDeviceCallback();
82     }
83 
84     @Override
onStop()85     protected void onStop() {
86         removeAudioDeviceCallback();
87         super.onStop();
88     }
89 
90     @TargetApi(23)
addAudioDeviceCallback()91     private void addAudioDeviceCallback(){
92         // Note that we will immediately receive a call to onDevicesAdded with the list of
93         // devices which are currently connected.
94         mAudioManager.registerAudioDeviceCallback(mDeviceCallback, null);
95     }
96 
97     @TargetApi(23)
removeAudioDeviceCallback()98     private void removeAudioDeviceCallback(){
99         mAudioManager.unregisterAudioDeviceCallback(mDeviceCallback);
100     }
101 
reportDeviceInfo(Collection<AudioDeviceInfo> devices)102     private void reportDeviceInfo(Collection<AudioDeviceInfo> devices) {
103         logClear();
104         StringBuffer report = new StringBuffer();
105         report.append("Device Report:\n");
106         for (AudioDeviceInfo deviceInfo : devices) {
107             report.append("\n==== Device =================== " + deviceInfo.getId() + "\n");
108             String item = AudioDeviceInfoConverter.toString(deviceInfo);
109             report.append(item);
110         }
111         report.append(reportAllMicrophones());
112         report.append(reportExtraDeviceInfo());
113         log(report.toString());
114     }
115 
reportAllMicrophones()116     public String reportAllMicrophones() {
117         StringBuffer report = new StringBuffer();
118         report.append("\n############################");
119         report.append("\nMicrophone Report:\n");
120         if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.P) {
121             try {
122                 List<MicrophoneInfo> micList = mAudioManager.getMicrophones();
123                 for (MicrophoneInfo micInfo : micList) {
124                     String micItem = MicrophoneInfoConverter.reportMicrophoneInfo(micInfo);
125                     report.append(micItem);
126                 }
127             } catch (IOException e) {
128                 e.printStackTrace();
129                 return e.getMessage();
130             }
131         } else {
132             report.append("\nMicrophoneInfo not available on V" + android.os.Build.VERSION.SDK_INT);
133         }
134         return report.toString();
135     }
136 
reportExtraDeviceInfo()137     private String reportExtraDeviceInfo() {
138         StringBuffer report = new StringBuffer();
139         report.append("\n\n############################");
140         report.append("\nExtras:");
141         String unprocessedSupport = mAudioManager.getParameters(AudioManager.PROPERTY_SUPPORT_AUDIO_SOURCE_UNPROCESSED);
142         report.append("\nSUPPORT_UNPROCESSED  : " + ((unprocessedSupport == null) ?  "null" : "yes"));
143 
144         report.append("\nProAudio Feature     : "
145             + getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUDIO_PRO));
146         report.append("\nLowLatency Feature   : "
147                 + getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUDIO_LOW_LATENCY));
148         report.append("\nMIDI Feature         : "
149                 + getPackageManager().hasSystemFeature(PackageManager.FEATURE_MIDI));
150         report.append("\nUSB Host Feature     : "
151                 + getPackageManager().hasSystemFeature(PackageManager.FEATURE_USB_HOST));
152         report.append("\nUSB Accessory Feature: "
153                 + getPackageManager().hasSystemFeature(PackageManager.FEATURE_USB_ACCESSORY));
154 
155         return report.toString();
156     }
157 
158     // Write to scrollable TextView
log(final String text)159     private void log(final String text) {
160         runOnUiThread(new Runnable() {
161             @Override
162             public void run() {
163                 mAutoTextView.append(text);
164                 mAutoTextView.append("\n");
165             }
166         });
167     }
168 
logClear()169     private void logClear() {
170         runOnUiThread(new Runnable() {
171             @Override
172             public void run() {
173                 mAutoTextView.setText("");
174             }
175         });
176     }
177 
178 }
179