/** 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();
    }
  }
 // This method is called when the proximity sensor reports a state change,
 // e.g. from "NEAR to FAR" or from "FAR to NEAR".
 private void onProximitySensorChangedState() {
   // The proximity sensor should only be activated when there are exactly two
   // available audio devices.
   if (audioDevices.size() == 2
       && audioDevices.contains(AppRTCAudioManager.AudioDevice.EARPIECE)
       && audioDevices.contains(AppRTCAudioManager.AudioDevice.SPEAKER_PHONE)) {
     if (proximitySensor.sensorReportsNearState()) {
       // Sensor reports that a "handset is being held up to a person's ear",
       // or "something is covering the light sensor".
       setAudioDevice(AppRTCAudioManager.AudioDevice.EARPIECE);
     } else {
       // Sensor reports that a "handset is removed from a person's ear", or
       // "the light sensor is no longer covered".
       setAudioDevice(AppRTCAudioManager.AudioDevice.SPEAKER_PHONE);
     }
   }
 }
  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);
  }
  public void close() {
    Log.d(TAG, "close");
    if (!initialized) {
      return;
    }

    unregisterForWiredHeadsetIntentBroadcast();

    // Restore previously stored audio states.
    setSpeakerphoneOn(savedIsSpeakerPhoneOn);
    setMicrophoneMute(savedIsMicrophoneMute);
    audioManager.setMode(savedAudioMode);
    audioManager.abandonAudioFocus(null);

    if (proximitySensor != null) {
      proximitySensor.stop();
      proximitySensor = null;
    }

    initialized = false;
  }