Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: media/base/android/java/src/org/chromium/media/AudioManagerAndroid.java

Issue 78033003: Adding device enumeration to Android device manager (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: try again Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package org.chromium.media; 5 package org.chromium.media;
6 6
7 import android.bluetooth.BluetoothAdapter;
8 import android.bluetooth.BluetoothManager;
7 import android.content.BroadcastReceiver; 9 import android.content.BroadcastReceiver;
8 import android.content.Context; 10 import android.content.Context;
9 import android.content.Intent; 11 import android.content.Intent;
10 import android.content.IntentFilter; 12 import android.content.IntentFilter;
11 import android.content.pm.PackageManager; 13 import android.content.pm.PackageManager;
12 import android.media.AudioFormat; 14 import android.media.AudioFormat;
13 import android.media.AudioManager; 15 import android.media.AudioManager;
14 import android.media.AudioRecord; 16 import android.media.AudioRecord;
15 import android.media.AudioTrack; 17 import android.media.AudioTrack;
16 import android.os.Build; 18 import android.os.Build;
19 import android.os.Process;
17 import android.util.Log; 20 import android.util.Log;
18 21
22 import java.util.Arrays;
23 import java.util.ArrayList;
24 import java.util.HashSet;
25 import java.util.List;
26 import java.util.Set;
27
19 import org.chromium.base.CalledByNative; 28 import org.chromium.base.CalledByNative;
20 import org.chromium.base.JNINamespace; 29 import org.chromium.base.JNINamespace;
21 30
22 @JNINamespace("media") 31 @JNINamespace("media")
23 class AudioManagerAndroid { 32 class AudioManagerAndroid {
24 private static final String TAG = "AudioManagerAndroid"; 33 private static final String TAG = "AudioManagerAndroid";
25 34
26 // Most of Google lead devices use 44.1K as the default sampling rate, 44.1K 35 /** Simple container for device information. */
27 // is also widely used on other android devices. 36 private static class AudioDeviceName {
37 private final int mId;
38 private final String mName;
39
40 private AudioDeviceName(int id, String name) {
41 mId = id;
42 mName = name;
43 }
44
45 @CalledByNative("AudioDeviceName")
46 private String id() { return String.valueOf(mId); }
47
48 @CalledByNative("AudioDeviceName")
49 private String name() { return mName; }
50 }
51
52 // Supported audio device types.
53 private static final int DEVICE_INVALID = 0;
54 private static final int DEVICE_SPEAKERPHONE = 1;
55 private static final int DEVICE_WIRED_HEADSET = 2;
56 private static final int DEVICE_EARPIECE = 3;
57 private static final int DEVICE_BLUETOOTH_HEADSET = 4;
58
59 // List of valid device types.
60 private static Integer[] VALID_DEVICES = new Integer[] {
61 DEVICE_SPEAKERPHONE,
62 DEVICE_WIRED_HEADSET,
63 DEVICE_EARPIECE,
64 DEVICE_BLUETOOTH_HEADSET,
65 };
66
67 // Maps audio device types to string values.
Jói 2013/11/29 14:40:46 Maybe it would be better to have this right after
henrika (OOO until Aug 14) 2013/11/29 15:31:49 Done.
68 // TODO(henrika): add support for proper detection of device names and
69 // localize the name strings.
70 private static final String[] DEVICE_NAMES = new String[] {
71 "Invalid device",
72 "Speakerphone",
73 "Wired headset", // With or without microphone
74 "Headset earpiece", // Only available on mobile phones
75 "Bluetooth headset",
76 };
77
78 // The device does not have any audio device.
Jói 2013/11/29 14:40:46 It would be cool to document the valid state trans
henrika (OOO until Aug 14) 2013/11/29 15:31:49 Added TODO.
79 static final int STATE_NO_DEVICE_SELECTED = 0;
80 // The speakerphone is on and an associated microphone is used.
81 static final int STATE_SPEAKERPHONE_ON = 1;
82 // The phone's earpiece is on and an associated microphone is used.
83 static final int STATE_EARPIECE_ON = 2;
84 // A wired headset (with or without a microphone) is plugged in.
85 static final int STATE_WIRED_HEADSET_ON = 3;
86 // The audio stream is being directed to a Bluetooth headset.
87 static final int STATE_BLUETOOTH_ON = 4;
88 // We've requested that the audio stream be directed to Bluetooth, but
89 // have not yet received a response from the framework.
90 static final int STATE_BLUETOOTH_TURNING_ON = 5;
91 // We've requested that the audio stream stop being directed to
92 // Bluetooth, but have not yet received a response from the framework.
93 static final int STATE_BLUETOOTH_TURNING_OFF = 6;
94
95 // Use 44.1kHz as the default sampling rate.
28 private static final int DEFAULT_SAMPLING_RATE = 44100; 96 private static final int DEFAULT_SAMPLING_RATE = 44100;
29 // Randomly picked up frame size which is close to return value on N4. 97 // Randomly picked up frame size which is close to return value on N4.
30 // Return this default value when 98 // Return this value when getProperty(PROPERTY_OUTPUT_FRAMES_PER_BUFFER)
31 // getProperty(PROPERTY_OUTPUT_FRAMES_PER_BUFFER) fails. 99 // fails.
32 private static final int DEFAULT_FRAME_PER_BUFFER = 256; 100 private static final int DEFAULT_FRAME_PER_BUFFER = 256;
33 101
34 private final AudioManager mAudioManager; 102 private final AudioManager mAudioManager;
35 private final Context mContext; 103 private final Context mContext;
36 104
37 private BroadcastReceiver mReceiver; 105 private boolean mHasBluetoothPermission = false;
38 private boolean mOriginalSpeakerStatus; 106 private boolean mIsInitialized = false;
107 private boolean mSavedSpeakerPhoneState;
108 private boolean mSavedMicrophoneMuteState;
39 109
40 @CalledByNative 110 private Integer mAudioDeviceState = STATE_NO_DEVICE_SELECTED;
41 public void setMode(int mode) {
42 try {
43 mAudioManager.setMode(mode);
44 } catch (SecurityException e) {
45 Log.e(TAG, "setMode exception: " + e.getMessage());
46 logDeviceInfo();
47 }
48 }
49 111
112 // Contains a list of currently available audio devices.
113 private Set<Integer> mAudioDevices = new HashSet<Integer>();
114
115 // Broadcast receiver for wired headset intent broadcasts.
116 private BroadcastReceiver mWiredHeadsetReceiver;
117
118 /** Construction */
50 @CalledByNative 119 @CalledByNative
51 private static AudioManagerAndroid createAudioManagerAndroid(Context context ) { 120 private static AudioManagerAndroid createAudioManagerAndroid(Context context ) {
52 return new AudioManagerAndroid(context); 121 return new AudioManagerAndroid(context);
53 } 122 }
54 123
55 private AudioManagerAndroid(Context context) { 124 private AudioManagerAndroid(Context context) {
56 mContext = context; 125 mContext = context;
57 mAudioManager = (AudioManager)mContext.getSystemService(Context.AUDIO_SE RVICE); 126 mAudioManager = (AudioManager)mContext.getSystemService(Context.AUDIO_SE RVICE);
58 } 127 }
59 128
129 /**
130 * Saves the initial speakerphone and microphone state.
131 * Populates the list of available audio devices and registers receivers
132 * for broadcasted intents related to wired headset and bluetooth devices.
133 */
60 @CalledByNative 134 @CalledByNative
61 public void registerHeadsetReceiver() { 135 public void init() {
62 if (mReceiver != null) { 136 if (mIsInitialized)
63 return; 137 return;
138
139 // Store microphone mute state and speakerphone state so it can
140 // be restored when closing.
141 mSavedSpeakerPhoneState = mAudioManager.isSpeakerphoneOn();
Jói 2013/11/29 14:40:46 Naming suggestion: mSavedIsSpeakerphoneOn and mSav
henrika (OOO until Aug 14) 2013/11/29 15:31:49 thx
142 mSavedMicrophoneMuteState = mAudioManager.isMicrophoneMute();
143
144 // Always enable speaker phone by default. This state might be reset
145 // by the wired headset receiver when it gets its initial sticky
146 // intent, if any.
147 setSpeakerphoneOn(true);
148 mAudioDeviceState = STATE_SPEAKERPHONE_ON;
149
150 // Initialize audio device list with things we know is always available.
151 if (hasEarpiece()) {
152 mAudioDevices.add(DEVICE_EARPIECE);
64 } 153 }
154 mAudioDevices.add(DEVICE_SPEAKERPHONE);
65 155
66 mOriginalSpeakerStatus = mAudioManager.isSpeakerphoneOn(); 156 // Register receiver for broadcasted intents related to adding/
67 if (!mOriginalSpeakerStatus) { 157 // removing a wired headset (Intent.ACTION_HEADSET_PLUG).
68 mAudioManager.setSpeakerphoneOn(true); 158 // Also starts routing to the wired headset/headphone if one is
69 } 159 // already attached (can be overridden by a Bluetooth headset).
70 IntentFilter filter = new IntentFilter(Intent.ACTION_HEADSET_PLUG); 160 registerForWiredHeadsetIntentBroadcast();
71 161
72 mReceiver = new BroadcastReceiver() { 162 // Start routing to Bluetooth if there's a connected device.
73 @Override 163 // TODO(henrika): the actual routing part is not implemented yet.
74 public void onReceive(Context context, Intent intent) { 164 // All we do currently is to detect if BT headset is attached or not.
75 if (Intent.ACTION_HEADSET_PLUG.equals(intent.getAction())) { 165 initBluetooth();
76 try { 166
77 mAudioManager.setSpeakerphoneOn( 167 mIsInitialized = true;
78 intent.getIntExtra("state", 0) == 0); 168 }
79 } catch (SecurityException e) { 169
80 Log.e(TAG, "setMode exception: " + e.getMessage()); 170 /**
81 logDeviceInfo(); 171 * Unregister all previously registered intent receivers and restore
82 } 172 * the stored state (stored in {@link #init()}).
83 } 173 */
84 } 174 @CalledByNative
85 }; 175 public void close() {
86 mContext.registerReceiver(mReceiver, filter); 176 if (!mIsInitialized)
177 return;
178
179 unregisterForWiredHeadsetIntentBroadcast();
180
181 // Restore previously stored audio states.
182 setMicrophoneMute(mSavedMicrophoneMuteState);
183 setSpeakerphoneOn(mSavedSpeakerPhoneState);
184
185 mIsInitialized = false;
87 } 186 }
88 187
89 @CalledByNative 188 @CalledByNative
90 public void unregisterHeadsetReceiver() { 189 public void setMode(int mode) {
91 mContext.unregisterReceiver(mReceiver); 190 try {
92 mReceiver = null; 191 mAudioManager.setMode(mode);
93 mAudioManager.setSpeakerphoneOn(mOriginalSpeakerStatus); 192 } catch (SecurityException e) {
193 Log.e(TAG, "setMode exception: " + e.getMessage());
194 logDeviceInfo();
195 }
94 } 196 }
95 197
96 private void logDeviceInfo() { 198 /**
97 Log.i(TAG, "Manufacturer:" + Build.MANUFACTURER + 199 * Activates, i.e., starts routing audio to, the specified audio device.
98 " Board: " + Build.BOARD + " Device: " + Build.DEVICE + 200 *
99 " Model: " + Build.MODEL + " PRODUCT: " + Build.PRODUCT); 201 * @param deviceId Unique device ID (integer converted to string)
202 * representing the selected device. This string is empty if the so-called
203 * default device is selected.
204 */
205 @CalledByNative
206 public void setDevice(String deviceId) {
207 if (deviceId.isEmpty()) {
208 logd("setDevice: default");
209 // Use a special selection scheme if the default device is selected.
210 // The "most unique" device will be selected; Bluetooth first, then
211 // wired headset and last the speaker phone.
212 if (mAudioDevices.contains(DEVICE_BLUETOOTH_HEADSET)) {
213 // TODO(henrika): possibly need improvements here if we are
214 // in a STATE_BLUETOOTH_TURNING_OFF state.
215 setAudioDevice(DEVICE_BLUETOOTH_HEADSET);
216 } else if (mAudioDevices.contains(DEVICE_WIRED_HEADSET)) {
217 setAudioDevice(DEVICE_WIRED_HEADSET);
218 } else {
219 setAudioDevice(DEVICE_SPEAKERPHONE);
220 }
221 } else {
222 logd("setDevice: " + deviceId);
223 // A non-default device is specified. Verify that it is valid
224 // device, and if so, start using it.
225 List<Integer> validIds = Arrays.asList(VALID_DEVICES);
226 Integer id = Integer.valueOf(deviceId);
227 if (validIds.contains(id)) {
228 setAudioDevice(id.intValue());
229 } else {
230 loge("Invalid device ID!");
231 }
232 }
233 }
234
235 /**
236 * @return the current list of available audio devices.
237 * Note that this call does not trigger any update of the list of devices,
238 * it only copies the current state in to the output array.
239 */
240 @CalledByNative
241 public AudioDeviceName[] getAudioInputDeviceNames() {
242 List<String> devices = new ArrayList<String>();
243 AudioDeviceName[] array = new AudioDeviceName[mAudioDevices.size()];
244 int i = 0;
245 for (Integer dev : mAudioDevices) {
246 array[i] = new AudioDeviceName(dev, DEVICE_NAMES[dev]);
247 devices.add(DEVICE_NAMES[dev]);
248 i++;
249 }
250 logd("getAudioInputDeviceNames: " + devices);
251 return array;
100 } 252 }
101 253
102 @CalledByNative 254 @CalledByNative
103 private int getNativeOutputSampleRate() { 255 private int getNativeOutputSampleRate() {
104 if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.J ELLY_BEAN_MR1) { 256 if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.J ELLY_BEAN_MR1) {
105 String sampleRateString = mAudioManager.getProperty( 257 String sampleRateString = mAudioManager.getProperty(
106 AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE); 258 AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE);
107 return (sampleRateString == null ? 259 return (sampleRateString == null ?
108 DEFAULT_SAMPLING_RATE : Integer.parseInt(sampleRateString)); 260 DEFAULT_SAMPLING_RATE : Integer.parseInt(sampleRateString));
109 } else { 261 } else {
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 } 310 }
159 311
160 @CalledByNative 312 @CalledByNative
161 private int getAudioLowLatencyOutputFrameSize() { 313 private int getAudioLowLatencyOutputFrameSize() {
162 String framesPerBuffer = 314 String framesPerBuffer =
163 mAudioManager.getProperty(AudioManager.PROPERTY_OUTPUT_FRAMES_PE R_BUFFER); 315 mAudioManager.getProperty(AudioManager.PROPERTY_OUTPUT_FRAMES_PE R_BUFFER);
164 return (framesPerBuffer == null ? 316 return (framesPerBuffer == null ?
165 DEFAULT_FRAME_PER_BUFFER : Integer.parseInt(framesPerBuffer)); 317 DEFAULT_FRAME_PER_BUFFER : Integer.parseInt(framesPerBuffer));
166 } 318 }
167 319
320 /** Sets the speaker phone mode. */
321 public void setSpeakerphoneOn(boolean on) {
322 boolean wasOn = mAudioManager.isSpeakerphoneOn();
323 if (wasOn == on) {
324 return;
325 }
326 mAudioManager.setSpeakerphoneOn(on);
327 }
328
329 /** Sets the microphone mute state. */
330 public void setMicrophoneMute(boolean on) {
331 boolean wasOn = mAudioManager.isMicrophoneMute();
Jói 2013/11/29 14:40:46 nit: wasMuted maybe instead of wasOn?
henrika (OOO until Aug 14) 2013/11/29 15:31:49 Done.
332 if (wasOn == on) {
333 return;
334 }
335 mAudioManager.setMicrophoneMute(on);
336 }
337
338 /** Gets the current microphone mute state. */
339 public boolean isMicrophoneMute() {
340 return mAudioManager.isMicrophoneMute();
341 }
342
343 /** Gets the current earpice state. */
344 private boolean hasEarpiece() {
345 boolean hasFeature = mContext.getPackageManager().hasSystemFeature(
Jói 2013/11/29 14:40:46 could just return directly
henrika (OOO until Aug 14) 2013/11/29 15:31:49 Done.
346 PackageManager.FEATURE_TELEPHONY);
347 return hasFeature;
348 }
349
350 /**
351 * Registers receiver for the broadcasted intent when a wired headset is
352 * plugged in or unplugged. The received intent will have an extra
353 * 'state' value where 0 means unplugged, and 1 means plugged.
354 */
355 private void registerForWiredHeadsetIntentBroadcast() {
356 IntentFilter filter = new IntentFilter();
357 filter.addAction(Intent.ACTION_HEADSET_PLUG);
358
359 /**
360 * Receiver which handles changes in wired headset availablilty.
361 */
362 mWiredHeadsetReceiver = new BroadcastReceiver() {
363 private static final int STATE_UNPLUGGED = 0;
364 private static final int STATE_PLUGGED = 1;
365 private static final int HAS_NO_MIC = 0;
366 private static final int HAS_MIC = 1;
367
368 @Override
369 public void onReceive(Context context, Intent intent) {
370 String action = intent.getAction();
371 if (action.equals(Intent.ACTION_HEADSET_PLUG)) {
Jói 2013/11/29 14:40:46 Will it not always equal this, since you have a fi
tommi (sloooow) - chröme 2013/11/29 15:04:33 +1 - and if it isn't then it might be better to sa
henrika (OOO until Aug 14) 2013/11/29 15:31:49 You guys ;-)
372 int state = intent.getIntExtra("state", STATE_UNPLUGGED);
373 int microphone = intent.getIntExtra("microphone", HAS_NO_MIC );
374 String name = intent.getStringExtra("name");
375 logd("==> onReceive: s=" + state
376 + ", m=" + microphone
377 + ", n=" + name
378 + ", s=" + isInitialStickyBroadcast());
379
380 switch (state) {
381 case STATE_UNPLUGGED:
382 // Wired headset and earpiece are mutually exclusive .
383 mAudioDevices.remove(DEVICE_WIRED_HEADSET);
384 if (hasEarpiece()) {
385 mAudioDevices.add(DEVICE_EARPIECE);
386 }
387 // If wired headset was used before it was unplugged ,
388 // switch to speaker phone. If it was not in use; ju st
389 // log the change.
390 if (mAudioDeviceState == STATE_WIRED_HEADSET_ON) {
391 setAudioDevice(DEVICE_SPEAKERPHONE);
392 } else {
393 reportUpdate();
394 }
395 break;
396 case STATE_PLUGGED:
397 // Wired headset and earpiece are mutually exclusive .
398 mAudioDevices.add(DEVICE_WIRED_HEADSET);
399 mAudioDevices.remove(DEVICE_EARPIECE);
400 setAudioDevice(DEVICE_WIRED_HEADSET);
401 break;
402 }
403 }
404 }
405 };
406
407 // Note: the intent we register for here is sticky, so it'll tell us
408 // immediately what the last action was (plugged or unplugged).
409 // It will enable us to set the speakerphone correctly.
410 mContext.registerReceiver(mWiredHeadsetReceiver, filter);
411 }
412
413 /** Unregister receiver for broadcasted ACTION_HEADSET_PLUG intent. */
414 private void unregisterForWiredHeadsetIntentBroadcast() {
415 mContext.unregisterReceiver(mWiredHeadsetReceiver);
416 mWiredHeadsetReceiver = null;
417 }
418
419
Jói 2013/11/29 14:40:46 nit: just one blank line?
henrika (OOO until Aug 14) 2013/11/29 15:31:49 Done.
420 /**
421 * Check if Bluetooth device is connected, register Bluetooth receiver
422 * and start routing to Bluetooth if a device is connected.
423 * TODO(henrika): currently only supports the detecion part at startup.
424 */
425 private void initBluetooth() {
426 // Bail out if we don't have the required permission.
427 mHasBluetoothPermission = mContext.checkPermission(
428 android.Manifest.permission.BLUETOOTH,
429 Process.myPid(),
430 Process.myUid()) == PackageManager.PERMISSION_GRANTED;
431 if (!mHasBluetoothPermission) {
432 loge("BLUETOOTH permission is missing!");
433 return;
434 }
435
436 // To get a BluetoothAdapter representing the local Bluetooth adapter,
437 // when running on JELLY_BEAN_MR1 (4.2) and below, call the static
438 // getDefaultAdapter() method; when running on JELLY_BEAN_MR2 (4.3) and
439 // higher, retrieve it through getSystemService(String) with
440 // BLUETOOTH_SERVICE.
441 // Note: Most methods require the BLUETOOTH permission.
442 BluetoothAdapter btAdapter = null;
443 if (android.os.Build.VERSION.SDK_INT <=
444 android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) {
445 // Use static method for Android 4.2 and below to get the
446 // BluetoothAdapter.
447 btAdapter = BluetoothAdapter.getDefaultAdapter();
448 } else {
449 // Use BluetoothManager to get the BluetoothAdapter for
450 // Android 4.3 and above.
451 BluetoothManager btManager =
452 (BluetoothManager)mContext.getSystemService(
453 Context.BLUETOOTH_SERVICE);
454 btAdapter = btManager.getAdapter();
455 }
456
457 if (btAdapter != null &&
458 // android.bluetooth.BluetoothAdapter.getProfileConnectionState
459 // requires BLUETOOTH permission.
460 android.bluetooth.BluetoothProfile.STATE_CONNECTED ==
461 btAdapter.getProfileConnectionState(
462 android.bluetooth.BluetoothProfile.HEADSET)) {
463 mAudioDevices.add(DEVICE_BLUETOOTH_HEADSET);
464 // TODO(henrika): ensure that we set the active audio
465 // device to Bluetooth (not trivial).
466 setAudioDevice(DEVICE_BLUETOOTH_HEADSET);
467 }
468 }
469
470 /**
471 * Changes selection of the currently active audio device.
472 *
473 * @param device Specifies the selected audio device.
474 */
475 public void setAudioDevice(int device) {
476 switch (device) {
477 case DEVICE_BLUETOOTH_HEADSET:
478 // TODO(henrika): add support for turning on an routing to
479 // BT here.
480 logd("--- TO BE IMPLEMENTED ---");
tommi (sloooow) - chröme 2013/11/29 15:04:33 use |if (DEBUG)| for debug logging?
henrika (OOO until Aug 14) 2013/11/29 15:31:49 Forgot, will do.
481 break;
482 case DEVICE_SPEAKERPHONE:
483 // TODO(henrika): turn off BT if required.
484 mAudioDeviceState = STATE_SPEAKERPHONE_ON;
485 setSpeakerphoneOn(true);
486 break;
487 case DEVICE_WIRED_HEADSET:
488 // TODO(henrika): turn off BT if required.
489 mAudioDeviceState = STATE_WIRED_HEADSET_ON;
490 setSpeakerphoneOn(false);
491 break;
492 case DEVICE_EARPIECE:
493 // TODO(henrika): turn off BT if required.
494 mAudioDeviceState = STATE_EARPIECE_ON;
495 setSpeakerphoneOn(false);
496 break;
497 default:
498 loge("Invalid audio device selection!");
499 break;
500 }
501 reportUpdate();
502 }
503
504 /**
505 * For now, just log the state change but the idea is that we should
506 * notifies a registered state change listener (if any) that there has
507 * been a change in the state.
508 * TODO(henrika): add support for state change listener.
509 */
510 private void reportUpdate() {
511 List<String> devices = new ArrayList<String>();
512 for (Integer dev : mAudioDevices) {
513 devices.add(DEVICE_NAMES[dev]);
514 }
515 logd("reportUpdate: state=" + mAudioDeviceState
516 + ", devices=" + devices);
517 }
518
519 private void logDeviceInfo() {
520 Log.i(TAG, "Manufacturer:" + Build.MANUFACTURER +
521 " Board: " + Build.BOARD + " Device: " + Build.DEVICE +
522 " Model: " + Build.MODEL + " PRODUCT: " + Build.PRODUCT);
523 }
524
525 /** Trivial helper method for debug logging */
526 private void logd(String msg) {
527 Log.d(TAG, msg);
528 }
529
530 /** Trivial helper method for error logging */
531 private void loge(String msg) {
532 Log.e(TAG, msg);
533 }
168 } 534 }
OLDNEW
« media/audio/android/audio_manager_android.cc ('K') | « media/audio/android/audio_manager_android.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698