/** Called each time a new audio device has been added or removed. */
  private void onAudioManagerChangedState() {
    Log.d(
        TAG,
        "onAudioManagerChangedState: devices="
            + audioDevices
            + ", selected="
            + selectedAudioDevice);

    // Enable the proximity sensor if there are two available audio devices
    // in the list. Given the current implementation, we know that the choice
    // will then be between EARPIECE and SPEAKER_PHONE.
    if (audioDevices.size() == 2) {
      AppRTCUtils.assertIsTrue(
          audioDevices.contains(AudioDevice.EARPIECE)
              && audioDevices.contains(AudioDevice.SPEAKER_PHONE));
      // Start the proximity sensor.
      proximitySensor.start();
    } else if (audioDevices.size() == 1) {
      // Stop the proximity sensor since it is no longer needed.
      proximitySensor.stop();
    } else {
      Log.e(TAG, "Invalid device list");
    }

    if (onStateChangeListener != null) {
      // Run callback to notify a listening client. The client can then
      // use public getters to query the new state.
      onStateChangeListener.run();
    }
  }
  private AppRTCAudioManager(Context context, Runnable deviceStateChangeListener) {
    apprtcContext = context;
    onStateChangeListener = deviceStateChangeListener;
    audioManager = ((AudioManager) context.getSystemService(Context.AUDIO_SERVICE));

    // Create and initialize the proximity sensor.
    // Tablet devices (e.g. Nexus 7) does not support proximity sensors.
    // Note that, the sensor will not be active until start() has been called.
    proximitySensor =
        AppRTCProximitySensor.create(
            context,
            new Runnable() {
              // This method will be called each time a state change is detected.
              // Example: user holds his hand over the device (closer than ~5 cm),
              // or removes his hand from the device.
              public void run() {
                onProximitySensorChangedState();
              }
            });
    AppRTCUtils.logDeviceInfo(TAG);
  }
  /** Changes selection of the currently active audio device. */
  public void setAudioDevice(AudioDevice device) {
    Log.d(TAG, "setAudioDevice(device=" + device + ")");
    AppRTCUtils.assertIsTrue(audioDevices.contains(device));

    switch (device) {
      case SPEAKER_PHONE:
        setSpeakerphoneOn(true);
        selectedAudioDevice = AudioDevice.SPEAKER_PHONE;
        break;
      case EARPIECE:
        setSpeakerphoneOn(false);
        selectedAudioDevice = AudioDevice.EARPIECE;
        break;
      case WIRED_HEADSET:
        setSpeakerphoneOn(false);
        selectedAudioDevice = AudioDevice.WIRED_HEADSET;
        break;
      default:
        Log.e(TAG, "Invalid audio device selection");
        break;
    }
    onAudioManagerChangedState();
  }