xref: /aosp_15_r20/external/oboe/apps/OboeTester/app/src/main/java/com/mobileer/oboetester/DeviceReportActivity.java (revision 05767d913155b055644481607e6fa1e35e2fe72c)
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.mobileer.oboetester;
18 
19 import android.annotation.TargetApi;
20 import android.app.Activity;
21 import android.content.Context;
22 import android.content.Intent;
23 import android.hardware.usb.UsbDevice;
24 import android.hardware.usb.UsbManager;
25 import android.media.AudioDeviceCallback;
26 import android.media.AudioDeviceInfo;
27 import android.media.AudioManager;
28 import android.media.MicrophoneInfo;
29 import android.media.midi.MidiDeviceInfo;
30 import android.media.midi.MidiManager;
31 import android.os.Build;
32 import android.os.Bundle;
33 import android.util.Log;
34 import android.view.Menu;
35 import android.view.MenuItem;
36 import android.widget.TextView;
37 import android.widget.Toast;
38 
39 import com.mobileer.audio_device.AudioDeviceInfoConverter;
40 
41 import java.io.IOException;
42 import java.util.Collection;
43 import java.util.HashMap;
44 import java.util.List;
45 import java.util.Set;
46 
47 /**
48  * Print a report of all the available audio devices.
49  */
50 public class DeviceReportActivity extends Activity {
51 
52     class MyAudioDeviceCallback extends AudioDeviceCallback {
53         private HashMap<Integer, AudioDeviceInfo> mDevices
54                 = new HashMap<Integer, AudioDeviceInfo>();
55 
56         @Override
onAudioDevicesAdded(AudioDeviceInfo[] addedDevices)57         public void onAudioDevicesAdded(AudioDeviceInfo[] addedDevices) {
58             for (AudioDeviceInfo info : addedDevices) {
59                 mDevices.put(info.getId(), info);
60             }
61             reportDeviceInfo(mDevices.values());
62         }
63 
onAudioDevicesRemoved(AudioDeviceInfo[] removedDevices)64         public void onAudioDevicesRemoved(AudioDeviceInfo[] removedDevices) {
65             for (AudioDeviceInfo info : removedDevices) {
66                 mDevices.remove(info.getId());
67             }
68             reportDeviceInfo(mDevices.values());
69         }
70     }
71 
72     MyAudioDeviceCallback mDeviceCallback = new MyAudioDeviceCallback();
73     private TextView      mAutoTextView;
74     private AudioManager  mAudioManager;
75     private UsbManager    mUsbManager;
76     private MidiManager mMidiManager;
77 
78     @Override
onCreate(Bundle savedInstanceState)79     protected void onCreate(Bundle savedInstanceState) {
80         super.onCreate(savedInstanceState);
81         setContentView(R.layout.activity_device_report);
82         mAutoTextView = (TextView) findViewById(R.id.text_log_device_report);
83         mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
84         mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
85         mMidiManager = (MidiManager) getSystemService(Context.MIDI_SERVICE);
86     }
87 
88     @Override
onCreateOptionsMenu(Menu menu)89     public boolean onCreateOptionsMenu(Menu menu) {
90         getMenuInflater().inflate(R.menu.menu_main, menu);
91         MenuItem settings = menu.findItem(R.id.action_share);
92         settings.setOnMenuItemClickListener(item -> {
93             if(mAutoTextView !=null) {
94                 Intent sendIntent = new Intent();
95                 sendIntent.setAction(Intent.ACTION_SEND);
96                 sendIntent.putExtra(Intent.EXTRA_TEXT, mAutoTextView.getText().toString());
97                 sendIntent.setType("text/plain");
98                 Intent shareIntent = Intent.createChooser(sendIntent, null);
99                 startActivity(shareIntent);
100             }
101             return false;
102         });
103         return true;
104     }
105 
106     @Override
onStart()107     protected void onStart() {
108         super.onStart();
109         addAudioDeviceCallback();
110     }
111 
112     @Override
onStop()113     protected void onStop() {
114         removeAudioDeviceCallback();
115         super.onStop();
116     }
117 
118     @TargetApi(23)
addAudioDeviceCallback()119     private void addAudioDeviceCallback(){
120         // Note that we will immediately receive a call to onDevicesAdded with the list of
121         // devices which are currently connected.
122         mAudioManager.registerAudioDeviceCallback(mDeviceCallback, null);
123     }
124 
125     @TargetApi(23)
removeAudioDeviceCallback()126     private void removeAudioDeviceCallback(){
127         mAudioManager.unregisterAudioDeviceCallback(mDeviceCallback);
128     }
129 
reportDeviceInfo(Collection<AudioDeviceInfo> devices)130     private void reportDeviceInfo(Collection<AudioDeviceInfo> devices) {
131         logClear();
132         StringBuffer report = new StringBuffer();
133         report.append("Device Report:\n");
134         report.append("App: ").append(MainActivity.getVersionText()).append("\n");
135         report.append("Device: ").append(Build.MANUFACTURER).append(", ").append(Build.MODEL)
136                 .append(", ").append(Build.PRODUCT).append("\n");
137 
138         report.append(reportExtraDeviceInfo());
139 
140         for (AudioDeviceInfo deviceInfo : devices) {
141             report.append("\n==== Device =================== " + deviceInfo.getId() + "\n");
142             String item = AudioDeviceInfoConverter.toString(deviceInfo);
143             report.append(item);
144         }
145         report.append(reportAllMicrophones());
146         report.append(reportUsbDevices());
147         report.append(reportMidiDevices());
148         log(report.toString());
149     }
150 
reportUsbDevices()151     public String reportUsbDevices() {
152         StringBuffer report = new StringBuffer();
153         report.append("\n############################");
154         report.append("\nUsb Device Report:\n");
155         try {
156             HashMap<String, UsbDevice> usbDeviceList = mUsbManager.getDeviceList();
157             for (UsbDevice usbDevice : usbDeviceList.values()) {
158                 report.append("\n==== USB Device ========= " + usbDevice.getDeviceId());
159                 report.append("\nProduct Name       : " + usbDevice.getProductName());
160                 report.append("\nProduct ID         : 0x" + Integer.toHexString(usbDevice.getProductId()));
161                 report.append("\nManufacturer Name  : " + usbDevice.getManufacturerName());
162                 report.append("\nVendor ID          : 0x" + Integer.toHexString(usbDevice.getVendorId()));
163                 report.append("\nDevice Name        : " + usbDevice.getDeviceName());
164                 report.append("\nDevice Protocol    : " + usbDevice.getDeviceProtocol());
165                 report.append("\nDevice Class       : " + usbDevice.getDeviceClass());
166                 report.append("\nDevice Subclass    : " + usbDevice.getDeviceSubclass());
167                 report.append("\nVersion            : " + usbDevice.getVersion());
168                 report.append("\n" + usbDevice);
169                 report.append("\n");
170             }
171         } catch (Exception e) {
172             Log.e(TestAudioActivity.TAG, "Caught ", e);
173             showErrorToast(e.getMessage());
174             report.append("\nERROR: " + e.getMessage() + "\n");
175         }
176         return report.toString();
177     }
178 
reportMidiDevices()179     public String reportMidiDevices() {
180         StringBuffer report = new StringBuffer();
181         report.append("\n############################");
182         report.append("\nMidi Device Report:\n");
183         try {
184             MidiDeviceInfo[] midiDeviceInfos = mMidiManager.getDevices();
185             for (MidiDeviceInfo midiDeviceInfo : midiDeviceInfos) {
186                 report.append("\n==== MIDI Device ========= " + midiDeviceInfo.getId());
187                 addMidiDeviceInfoToDeviceReport(midiDeviceInfo, report);
188             }
189             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
190                 Set<MidiDeviceInfo> umpDeviceInfos =
191                         mMidiManager.getDevicesForTransport(MidiManager.TRANSPORT_UNIVERSAL_MIDI_PACKETS);
192                 for (MidiDeviceInfo midiDeviceInfo : umpDeviceInfos) {
193                     report.append("\n==== UMP Device ========= " + midiDeviceInfo.getId());
194                     addMidiDeviceInfoToDeviceReport(midiDeviceInfo, report);
195                 }
196             }
197         } catch (Exception e) {
198             Log.e(TestAudioActivity.TAG, "Caught ", e);
199             showErrorToast(e.getMessage());
200             report.append("\nERROR: " + e.getMessage() + "\n");
201         }
202         return report.toString();
203     }
204 
addMidiDeviceInfoToDeviceReport(MidiDeviceInfo midiDeviceInfo, StringBuffer report)205     private void addMidiDeviceInfoToDeviceReport(MidiDeviceInfo midiDeviceInfo,
206                                                  StringBuffer report){
207         report.append("\nInput Count        : " + midiDeviceInfo.getInputPortCount());
208         report.append("\nOutput Count       : " + midiDeviceInfo.getOutputPortCount());
209         report.append("\nType               : " + midiDeviceInfo.getType());
210         report.append("\nIs Private         : " + midiDeviceInfo.isPrivate());
211         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
212             report.append("\nDefault Protocol   : " + midiDeviceInfo.getDefaultProtocol());
213         }
214         report.append("\n" + midiDeviceInfo);
215         report.append("\n");
216     }
217 
reportAllMicrophones()218     public String reportAllMicrophones() {
219         StringBuffer report = new StringBuffer();
220         report.append("\n############################");
221         report.append("\nMicrophone Report:\n");
222         if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.P) {
223             try {
224                 List<MicrophoneInfo> micList = mAudioManager.getMicrophones();
225                 for (MicrophoneInfo micInfo : micList) {
226                     String micItem = MicrophoneInfoConverter.reportMicrophoneInfo(micInfo);
227                     report.append(micItem);
228                 }
229             } catch (IOException e) {
230                 Log.e(TestAudioActivity.TAG, "Caught ", e);
231                 return e.getMessage();
232             } catch (Exception e) {
233                 Log.e(TestAudioActivity.TAG, "Caught ", e);
234                 showErrorToast(e.getMessage());
235                 report.append("\nERROR: " + e.getMessage() + "\n");
236             }
237         } else {
238             report.append("\nMicrophoneInfo not available on V" + android.os.Build.VERSION.SDK_INT);
239         }
240         return report.toString();
241     }
242 
reportExtraDeviceInfo()243     private String reportExtraDeviceInfo() {
244         StringBuffer report = new StringBuffer();
245         report.append("\n\n############################");
246         report.append("\nAudioManager:");
247         report.append(AudioQueryTools.getAudioManagerReport(mAudioManager));
248         report.append("\n\nFeatures:");
249         report.append(AudioQueryTools.getAudioFeatureReport(getPackageManager()));
250         report.append(AudioQueryTools.getMediaPerformanceClass());
251         report.append("\n\nProperties:");
252         report.append(AudioQueryTools.getAudioPropertyReport());
253         return report.toString();
254     }
255 
256     // Write to scrollable TextView
log(final String text)257     private void log(final String text) {
258         runOnUiThread(new Runnable() {
259             @Override
260             public void run() {
261                 mAutoTextView.append(text);
262                 mAutoTextView.append("\n");
263             }
264         });
265     }
266 
logClear()267     private void logClear() {
268         runOnUiThread(new Runnable() {
269             @Override
270             public void run() {
271                 mAutoTextView.setText("");
272             }
273         });
274     }
275 
showErrorToast(String message)276     protected void showErrorToast(String message) {
277         String text = "Error: " + message;
278         Log.e(TestAudioActivity.TAG, text);
279         showToast(text);
280     }
281 
showToast(final String message)282     protected void showToast(final String message) {
283         runOnUiThread(new Runnable() {
284             @Override
285             public void run() {
286                 Toast.makeText(DeviceReportActivity.this,
287                         message,
288                         Toast.LENGTH_SHORT).show();
289             }
290         });
291     }
292 }
293