Using SDK audio helper instead of app's

This commit is contained in:
Sylvain Berfini 2021-01-21 14:32:30 +01:00
parent dfb499d073
commit f55a029192
10 changed files with 68 additions and 681 deletions

View file

@ -187,6 +187,7 @@ dependencies {
if (firebaseEnabled()) {
implementation 'com.google.firebase:firebase-messaging:19.0.1'
}
implementation 'androidx.media:media:1.2.0'
implementation 'androidx.recyclerview:recyclerview:1.0.0'
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'com.google.android:flexbox:1.1.0'

View file

@ -185,7 +185,6 @@ public class LinphoneManager implements SensorEventListener {
if (mCore != null) {
if (mCore.getCallsNb() > 0) {
mCallManager.acceptCall(call);
mAudioManager.routeAudioToEarPiece();
}
}
}

View file

@ -20,9 +20,7 @@
package org.linphone.assistant;
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.media.AudioManager;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;
@ -117,13 +115,9 @@ public class EchoCancellerCalibrationAssistantActivity extends AssistantActivity
Core core, EcCalibratorStatus status, int delayMs) {
if (status == EcCalibratorStatus.InProgress) return;
core.removeListener(this);
LinphoneManager.getAudioManager().routeAudioToEarPiece();
goToLinphoneActivity();
((AudioManager) getSystemService(Context.AUDIO_SERVICE))
.setMode(AudioManager.MODE_NORMAL);
}
});
LinphoneManager.getAudioManager().startEcCalibration();
LinphoneManager.getCore().startEchoCancellerCalibration();
}
}

View file

@ -19,69 +19,29 @@
*/
package org.linphone.call;
import static android.media.AudioManager.MODE_RINGTONE;
import static android.media.AudioManager.STREAM_RING;
import static android.media.AudioManager.STREAM_VOICE_CALL;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadset;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Vibrator;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.view.KeyEvent;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.List;
import org.linphone.LinphoneContext;
import org.linphone.LinphoneManager;
import org.linphone.R;
import org.linphone.compatibility.Compatibility;
import org.linphone.core.Address;
import org.linphone.core.AudioDevice;
import org.linphone.core.Call;
import org.linphone.core.Core;
import org.linphone.core.CoreListenerStub;
import org.linphone.core.EcCalibratorStatus;
import org.linphone.core.tools.Log;
import org.linphone.receivers.BluetoothReceiver;
import org.linphone.receivers.HeadsetReceiver;
import org.linphone.settings.LinphonePreferences;
public class AndroidAudioManager {
private Context mContext;
private AudioManager mAudioManager;
private Call mRingingCall;
private MediaPlayer mRingerPlayer;
private final Vibrator mVibrator;
private BluetoothAdapter mBluetoothAdapter;
private BluetoothHeadset mBluetoothHeadset;
private BluetoothReceiver mBluetoothReceiver;
private HeadsetReceiver mHeadsetReceiver;
private boolean mHeadsetReceiverRegistered;
private boolean mIsRinging;
private boolean mAudioFocused;
private boolean mEchoTesterIsRunning;
private boolean mIsBluetoothHeadsetConnected;
private boolean mIsBluetoothHeadsetScoConnected;
private boolean mEchoTesterIsRunning = false;
private CoreListenerStub mListener;
public AndroidAudioManager(Context context) {
mContext = context;
mAudioManager = ((AudioManager) context.getSystemService(Context.AUDIO_SERVICE));
mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
mEchoTesterIsRunning = false;
mHeadsetReceiverRegistered = false;
startBluetooth();
mListener =
new CoreListenerStub() {
@ -91,36 +51,9 @@ public class AndroidAudioManager {
final Call call,
final Call.State state,
final String message) {
if (state == Call.State.IncomingReceived
|| (state == Call.State.IncomingEarlyMedia
&& mContext.getResources()
.getBoolean(
R.bool.allow_ringing_while_early_media))) {
// Brighten screen for at least 10 seconds
if (core.getCallsNb() == 1) {
requestAudioFocus(STREAM_RING);
mRingingCall = call;
startRinging(call.getRemoteAddress());
// otherwise there is the beep
}
} else if (call == mRingingCall && mIsRinging) {
// previous state was ringing, so stop ringing
stopRinging();
}
if (state == Call.State.Connected) {
if (core.getCallsNb() == 1) {
// It is for incoming calls, because outgoing calls enter
// MODE_IN_COMMUNICATION immediately when they start.
// However, incoming call first use the MODE_RINGING to play the
// local ring.
if (call.getDir() == Call.Dir.Incoming) {
setAudioManagerInCallMode();
// mAudioManager.abandonAudioFocus(null);
requestAudioFocus(STREAM_VOICE_CALL);
}
if (!mIsBluetoothHeadsetConnected) {
if (!isBluetoothHeadsetConnected()) {
if (mContext.getResources().getBoolean(R.bool.isTablet)) {
routeAudioToSpeaker();
} else {
@ -130,70 +63,11 @@ public class AndroidAudioManager {
routeAudioToEarPiece();
}
}
}
// Only register this one when a call is active
enableHeadsetReceiver();
}
} else if (state == Call.State.End || state == Call.State.Error) {
if (core.getCallsNb() == 0) {
if (mAudioFocused) {
int res = mAudioManager.abandonAudioFocus(null);
Log.d(
"[Audio Manager] Audio focus released a bit later: "
+ (res
== AudioManager
.AUDIOFOCUS_REQUEST_GRANTED
? "Granted"
: "Denied"));
mAudioFocused = false;
}
// Only register this one when a call is active
if (mHeadsetReceiver != null && mHeadsetReceiverRegistered) {
Log.i("[Audio Manager] Unregistering headset receiver");
mContext.unregisterReceiver(mHeadsetReceiver);
mHeadsetReceiverRegistered = false;
}
TelephonyManager tm =
(TelephonyManager)
mContext.getSystemService(
Context.TELEPHONY_SERVICE);
if (tm.getCallState() == TelephonyManager.CALL_STATE_IDLE) {
Log.d(
"[Audio Manager] ---AndroidAudioManager: back to MODE_NORMAL");
mAudioManager.setMode(AudioManager.MODE_NORMAL);
Log.d(
"[Audio Manager] All call terminated, routing back to earpiece");
routeAudioToEarPiece();
}
}
}
if (state == Call.State.OutgoingInit) {
// Enter the MODE_IN_COMMUNICATION mode as soon as possible, so that
// ringback is heard normally in earpiece or bluetooth receiver.
setAudioManagerInCallMode();
requestAudioFocus(STREAM_VOICE_CALL);
if (mIsBluetoothHeadsetConnected) {
routeAudioToBluetooth();
}
}
if (state == Call.State.StreamsRunning) {
setAudioManagerInCallMode();
if (mIsBluetoothHeadsetConnected) {
} else {
routeAudioToBluetooth();
}
}
}
@Override
public void onEcCalibrationResult(
Core core, EcCalibratorStatus status, int delay_ms) {
mAudioManager.setMode(AudioManager.MODE_NORMAL);
mAudioManager.abandonAudioFocus(null);
Log.i("[Audio Manager] Set audio mode on 'Normal'");
}
};
@ -204,16 +78,6 @@ public class AndroidAudioManager {
}
public void destroy() {
if (mBluetoothAdapter != null && mBluetoothHeadset != null) {
Log.i("[Audio Manager] [Bluetooth] Closing HEADSET profile proxy");
mBluetoothAdapter.closeProfileProxy(BluetoothProfile.HEADSET, mBluetoothHeadset);
}
Log.i("[Audio Manager] [Bluetooth] Unegistering bluetooth receiver");
if (mBluetoothReceiver != null) {
mContext.unregisterReceiver(mBluetoothReceiver);
}
Core core = LinphoneManager.getCore();
if (core != null) {
core.removeListener(mListener);
@ -222,10 +86,6 @@ public class AndroidAudioManager {
/* Audio routing */
public void setAudioManagerModeNormal() {
mAudioManager.setMode(AudioManager.MODE_NORMAL);
}
public void routeAudioToEarPiece() {
routeAudioToSpeakerHelper(false);
}
@ -244,41 +104,17 @@ public class AndroidAudioManager {
/* Echo cancellation */
public void startEcCalibration() {
Core core = LinphoneManager.getCore();
if (core == null) {
return;
}
routeAudioToSpeaker();
setAudioManagerInCallMode();
Log.i("[Audio Manager] Set audio mode on 'Voice Communication'");
requestAudioFocus(STREAM_VOICE_CALL);
int oldVolume = mAudioManager.getStreamVolume(STREAM_VOICE_CALL);
int maxVolume = mAudioManager.getStreamMaxVolume(STREAM_VOICE_CALL);
mAudioManager.setStreamVolume(STREAM_VOICE_CALL, maxVolume, 0);
core.startEchoCancellerCalibration();
mAudioManager.setStreamVolume(STREAM_VOICE_CALL, oldVolume, 0);
}
public void startEchoTester() {
Core core = LinphoneManager.getCore();
if (core == null) {
return;
}
routeAudioToSpeaker();
setAudioManagerInCallMode();
Log.i("[Audio Manager] Set audio mode on 'Voice Communication'");
requestAudioFocus(STREAM_VOICE_CALL);
int maxVolume = mAudioManager.getStreamMaxVolume(STREAM_VOICE_CALL);
int sampleRate;
mAudioManager.setStreamVolume(STREAM_VOICE_CALL, maxVolume, 0);
String sampleRateProperty =
mAudioManager.getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE);
sampleRate = Integer.parseInt(sampleRateProperty);
core.startEchoTester(sampleRate);
mEchoTesterIsRunning = true;
core.startEchoTester(sampleRate);
}
public void stopEchoTester() {
@ -287,10 +123,8 @@ public class AndroidAudioManager {
return;
}
mEchoTesterIsRunning = false;
core.stopEchoTester();
routeAudioToEarPiece();
mAudioManager.setMode(AudioManager.MODE_NORMAL);
mEchoTesterIsRunning = false;
Log.i("[Audio Manager] Set audio mode on 'Normal'");
}
@ -309,107 +143,23 @@ public class AndroidAudioManager {
return false;
}
private void setAudioManagerInCallMode() {
if (mAudioManager.getMode() == AudioManager.MODE_IN_COMMUNICATION) {
Log.w("[Audio Manager] already in MODE_IN_COMMUNICATION, skipping...");
return;
}
Log.d("[Audio Manager] Mode: MODE_IN_COMMUNICATION");
mAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
}
private void requestAudioFocus(int stream) {
if (!mAudioFocused) {
int res =
mAudioManager.requestAudioFocus(
null, stream, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE);
Log.d(
"[Audio Manager] Audio focus requested: "
+ (res == AudioManager.AUDIOFOCUS_REQUEST_GRANTED
? "Granted"
: "Denied"));
if (res == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) mAudioFocused = true;
}
}
private synchronized void startRinging(Address remoteAddress) {
if (!LinphonePreferences.instance().isDeviceRingtoneEnabled()) {
// Enable speaker audio route, linphone library will do the ringing itself automatically
routeAudioToSpeaker();
return;
}
boolean doNotDisturbPolicyAllowsRinging =
Compatibility.isDoNotDisturbPolicyAllowingRinging(mContext, remoteAddress);
if (!doNotDisturbPolicyAllowsRinging) {
Log.e("[Audio Manager] Do not ring as Android Do Not Disturb Policy forbids it");
return;
}
routeAudioToSpeaker();
mAudioManager.setMode(MODE_RINGTONE);
try {
if ((mAudioManager.getRingerMode() == AudioManager.RINGER_MODE_VIBRATE
|| mAudioManager.getRingerMode() == AudioManager.RINGER_MODE_NORMAL)
&& mVibrator != null
&& LinphonePreferences.instance().isIncomingCallVibrationEnabled()) {
Compatibility.vibrate(mVibrator);
}
if (mRingerPlayer == null) {
requestAudioFocus(STREAM_RING);
mRingerPlayer = new MediaPlayer();
mRingerPlayer.setAudioStreamType(STREAM_RING);
String ringtone =
LinphonePreferences.instance()
.getRingtone(Settings.System.DEFAULT_RINGTONE_URI.toString());
try {
if (ringtone.startsWith("content://")) {
mRingerPlayer.setDataSource(mContext, Uri.parse(ringtone));
} else {
FileInputStream fis = new FileInputStream(ringtone);
mRingerPlayer.setDataSource(fis.getFD());
fis.close();
}
} catch (IOException e) {
Log.e(e, "[Audio Manager] Cannot set ringtone");
}
mRingerPlayer.prepare();
mRingerPlayer.setLooping(true);
mRingerPlayer.start();
} else {
Log.w("[Audio Manager] Already ringing");
}
} catch (Exception e) {
Log.e(e, "[Audio Manager] Cannot handle incoming call");
}
mIsRinging = true;
}
private synchronized void stopRinging() {
if (mRingerPlayer != null) {
mRingerPlayer.stop();
mRingerPlayer.release();
mRingerPlayer = null;
}
if (mVibrator != null) {
mVibrator.cancel();
}
mIsRinging = false;
}
private void routeAudioToSpeakerHelper(boolean speakerOn) {
Log.w("[Audio Manager] Routing audio to " + (speakerOn ? "speaker" : "earpiece"));
if (mIsBluetoothHeadsetScoConnected) {
Log.w("[Audio Manager] [Bluetooth] Disabling bluetooth audio route");
changeBluetoothSco(false);
}
mAudioManager.setSpeakerphoneOn(speakerOn);
if (LinphoneManager.getCore().getCallsNb() == 0) return;
Call currentCall = LinphoneManager.getCore().getCurrentCall();
if (currentCall == null) currentCall = LinphoneManager.getCore().getCalls()[0];
if (currentCall == null) return;
for (AudioDevice audioDevice : LinphoneManager.getCore().getAudioDevices()) {
if (speakerOn && audioDevice.getType() == AudioDevice.Type.Speaker) {
currentCall.setOutputAudioDevice(audioDevice);
return;
} else if (!speakerOn && audioDevice.getType() == AudioDevice.Type.Earpiece) {
currentCall.setOutputAudioDevice(audioDevice);
return;
}
}
}
private void adjustVolume(int i) {
@ -419,7 +169,7 @@ public class AndroidAudioManager {
}
int stream = STREAM_VOICE_CALL;
if (mIsBluetoothHeadsetScoConnected) {
if (isUsingBluetoothAudioRoute()) {
Log.i(
"[Audio Manager] Bluetooth is connected, try to change the volume on STREAM_BLUETOOTH_SCO");
stream = 6; // STREAM_BLUETOOTH_SCO, it's hidden...
@ -433,194 +183,45 @@ public class AndroidAudioManager {
AudioManager.FLAG_SHOW_UI);
}
// Bluetooth
public synchronized void bluetoothHeadetConnectionChanged(boolean connected) {
mIsBluetoothHeadsetConnected = connected;
mAudioManager.setBluetoothScoOn(connected);
if (LinphoneContext.isReady()) LinphoneManager.getCallManager().refreshInCallActions();
}
public synchronized void bluetoothHeadetAudioConnectionChanged(boolean connected) {
mIsBluetoothHeadsetScoConnected = connected;
mAudioManager.setBluetoothScoOn(connected);
public synchronized boolean isUsingBluetoothAudioRoute() {
if (LinphoneManager.getCore().getCallsNb() == 0) return false;
Call currentCall = LinphoneManager.getCore().getCurrentCall();
if (currentCall == null) currentCall = LinphoneManager.getCore().getCalls()[0];
if (currentCall == null) return false;
AudioDevice audioDevice = currentCall.getOutputAudioDevice();
Log.i("[Audio Manager] Currently used audio device: ", audioDevice.getDeviceName());
return audioDevice.getType() == AudioDevice.Type.Bluetooth;
}
public synchronized boolean isBluetoothHeadsetConnected() {
return mIsBluetoothHeadsetConnected;
for (AudioDevice audioDevice : LinphoneManager.getCore().getAudioDevices()) {
if (audioDevice.getType() == AudioDevice.Type.Bluetooth
&& audioDevice.hasCapability(AudioDevice.Capabilities.CapabilityPlay)) {
Log.i("[Audio Manager] Found bluetooth device: ", audioDevice.getDeviceName());
return true;
}
public synchronized void bluetoothHeadetScoConnectionChanged(boolean connected) {
mIsBluetoothHeadsetScoConnected = connected;
if (LinphoneContext.isReady()) LinphoneManager.getCallManager().refreshInCallActions();
}
public synchronized boolean isUsingBluetoothAudioRoute() {
return mIsBluetoothHeadsetScoConnected;
return false;
}
public synchronized void routeAudioToBluetooth() {
if (!isBluetoothHeadsetConnected()) {
Log.w("[Audio Manager] [Bluetooth] No headset connected");
if (LinphoneManager.getCore().getCallsNb() == 0) return;
Call currentCall = LinphoneManager.getCore().getCurrentCall();
if (currentCall == null) currentCall = LinphoneManager.getCore().getCalls()[0];
if (currentCall == null) return;
for (AudioDevice audioDevice : LinphoneManager.getCore().getAudioDevices()) {
if (audioDevice.getType() == AudioDevice.Type.Bluetooth
&& audioDevice.hasCapability(AudioDevice.Capabilities.CapabilityPlay)) {
Log.i(
"[Audio Manager] Found bluetooth audio device",
audioDevice.getDeviceName(),
", routing audio to it");
currentCall.setOutputAudioDevice(audioDevice);
return;
}
if (mAudioManager.getMode() != AudioManager.MODE_IN_COMMUNICATION) {
}
Log.w(
"[Audio Manager] [Bluetooth] Changing audio mode to MODE_IN_COMMUNICATION and requesting STREAM_VOICE_CALL focus");
mAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
requestAudioFocus(STREAM_VOICE_CALL);
}
changeBluetoothSco(true);
}
private synchronized void changeBluetoothSco(final boolean enable) {
// IT WILL TAKE A CERTAIN NUMBER OF CALLS TO EITHER START/STOP BLUETOOTH SCO FOR IT TO WORK
if (enable && mIsBluetoothHeadsetScoConnected) {
Log.i("[Audio Manager] [Bluetooth] SCO already enabled, skipping");
return;
} else if (!enable && !mIsBluetoothHeadsetScoConnected) {
Log.i("[Audio Manager] [Bluetooth] SCO already disabled, skipping");
return;
}
new Thread() {
@Override
public void run() {
Log.i("[Audio Manager] [Bluetooth] SCO start/stop thread started");
boolean resultAcknowledged;
int retries = 0;
do {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
Log.e(e);
}
synchronized (AndroidAudioManager.this) {
if (enable) {
Log.i(
"[Audio Manager] [Bluetooth] Starting SCO: try number "
+ retries);
mAudioManager.startBluetoothSco();
} else {
Log.i(
"[Audio Manager] [Bluetooth] Stopping SCO: try number "
+ retries);
mAudioManager.stopBluetoothSco();
}
resultAcknowledged = isUsingBluetoothAudioRoute() == enable;
retries++;
}
} while (!resultAcknowledged && retries < 10);
}
}.start();
}
public void bluetoothAdapterStateChanged() {
if (mBluetoothAdapter.isEnabled()) {
Log.i("[Audio Manager] [Bluetooth] Adapter enabled");
mIsBluetoothHeadsetConnected = false;
mIsBluetoothHeadsetScoConnected = false;
BluetoothProfile.ServiceListener bluetoothServiceListener =
new BluetoothProfile.ServiceListener() {
public void onServiceConnected(int profile, BluetoothProfile proxy) {
if (profile == BluetoothProfile.HEADSET) {
Log.i("[Audio Manager] [Bluetooth] HEADSET profile connected");
mBluetoothHeadset = (BluetoothHeadset) proxy;
List<BluetoothDevice> devices =
mBluetoothHeadset.getConnectedDevices();
if (devices.size() > 0) {
Log.i(
"[Audio Manager] [Bluetooth] A device is already connected");
bluetoothHeadetConnectionChanged(true);
}
Log.i("[Audio Manager] [Bluetooth] Registering bluetooth receiver");
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED);
filter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
filter.addAction(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED);
filter.addAction(
BluetoothHeadset.ACTION_VENDOR_SPECIFIC_HEADSET_EVENT);
Intent sticky =
mContext.registerReceiver(mBluetoothReceiver, filter);
Log.i("[Audio Manager] [Bluetooth] Bluetooth receiver registered");
int state =
sticky.getIntExtra(
AudioManager.EXTRA_SCO_AUDIO_STATE,
AudioManager.SCO_AUDIO_STATE_DISCONNECTED);
if (state == AudioManager.SCO_AUDIO_STATE_CONNECTED) {
Log.i(
"[Audio Manager] [Bluetooth] Bluetooth headset SCO connected");
bluetoothHeadetScoConnectionChanged(true);
} else if (state == AudioManager.SCO_AUDIO_STATE_DISCONNECTED) {
Log.i(
"[Audio Manager] [Bluetooth] Bluetooth headset SCO disconnected");
bluetoothHeadetScoConnectionChanged(false);
} else if (state == AudioManager.SCO_AUDIO_STATE_CONNECTING) {
Log.i(
"[Audio Manager] [Bluetooth] Bluetooth headset SCO connecting");
} else if (state == AudioManager.SCO_AUDIO_STATE_ERROR) {
Log.i(
"[Audio Manager] [Bluetooth] Bluetooth headset SCO connection error");
} else {
Log.w(
"[Audio Manager] [Bluetooth] Bluetooth headset unknown SCO state changed: "
+ state);
}
}
}
public void onServiceDisconnected(int profile) {
if (profile == BluetoothProfile.HEADSET) {
Log.i("[Audio Manager] [Bluetooth] HEADSET profile disconnected");
mBluetoothHeadset = null;
mIsBluetoothHeadsetConnected = false;
mIsBluetoothHeadsetScoConnected = false;
}
}
};
mBluetoothAdapter.getProfileProxy(
mContext, bluetoothServiceListener, BluetoothProfile.HEADSET);
} else {
Log.w("[Audio Manager] [Bluetooth] Adapter disabled");
}
}
private void startBluetooth() {
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter != null) {
Log.i("[Audio Manager] [Bluetooth] Adapter found");
if (mAudioManager.isBluetoothScoAvailableOffCall()) {
Log.i("[Audio Manager] [Bluetooth] SCO available off call, continue");
} else {
Log.w("[Audio Manager] [Bluetooth] SCO not available off call !");
}
mBluetoothReceiver = new BluetoothReceiver();
IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
mContext.registerReceiver(mBluetoothReceiver, filter);
bluetoothAdapterStateChanged();
}
}
// HEADSET
private void enableHeadsetReceiver() {
mHeadsetReceiver = new HeadsetReceiver();
Log.i("[Audio Manager] Registering headset receiver");
mContext.registerReceiver(
mHeadsetReceiver, new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY));
mContext.registerReceiver(
mHeadsetReceiver, new IntentFilter(AudioManager.ACTION_HEADSET_PLUG));
mHeadsetReceiverRegistered = true;
"[Audio Manager] Didn't find any bluetooth audio device, keeping default audio route");
}
}

View file

@ -430,6 +430,14 @@ public class CallActivity extends LinphoneGenericActivity
updateButtons();
updateCallsList();
}
@Override
public void onAudioDevicesListUpdated(@NonNull Core core) {
if (mAudioManager.isBluetoothHeadsetConnected()) {
mAudioManager.routeAudioToBluetooth();
}
updateButtons();
}
};
mCore = LinphoneManager.getCore();

View file

@ -50,6 +50,7 @@ import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.appcompat.view.menu.MenuBuilder;
import androidx.appcompat.view.menu.MenuPopupHelper;
import androidx.core.view.inputmethod.InputConnectionCompat;
@ -1210,6 +1211,9 @@ public class ChatMessagesFragment extends Fragment
* Chat room callbacks
*/
@Override
public void onNewEvent(@NonNull ChatRoom chatRoom, @NonNull EventLog eventLog) {}
@Override
public void onChatMessageSent(ChatRoom cr, EventLog event) {
((ChatMessagesGenericAdapter) mChatEventsList.getAdapter()).addToHistory(event);

View file

@ -1,145 +0,0 @@
/*
* Copyright (c) 2010-2019 Belledonne Communications SARL.
*
* This file is part of linphone-android
* (see https://www.linphone.org).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.linphone.receivers;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothHeadset;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import org.linphone.LinphoneManager;
import org.linphone.core.tools.Log;
public class BluetoothReceiver extends BroadcastReceiver {
public BluetoothReceiver() {
super();
Log.i("[Bluetooth] Bluetooth receiver created");
}
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.i("[Bluetooth] Bluetooth broadcast received");
if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
switch (state) {
case BluetoothAdapter.STATE_OFF:
Log.w("[Bluetooth] Adapter has been turned off");
break;
case BluetoothAdapter.STATE_TURNING_OFF:
Log.w("[Bluetooth] Adapter is being turned off");
break;
case BluetoothAdapter.STATE_ON:
Log.i("[Bluetooth] Adapter has been turned on");
LinphoneManager.getAudioManager().bluetoothAdapterStateChanged();
break;
case BluetoothAdapter.STATE_TURNING_ON:
Log.i("[Bluetooth] Adapter is being turned on");
break;
case BluetoothAdapter.ERROR:
Log.e("[Bluetooth] Adapter is in error state !");
break;
default:
Log.w("[Bluetooth] Unknown adapter state: ", state);
break;
}
} else if (action.equals(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)) {
int state =
intent.getIntExtra(
BluetoothHeadset.EXTRA_STATE, BluetoothHeadset.STATE_DISCONNECTED);
if (state == BluetoothHeadset.STATE_CONNECTED) {
Log.i("[Bluetooth] Bluetooth headset connected");
LinphoneManager.getAudioManager().bluetoothHeadetConnectionChanged(true);
} else if (state == BluetoothHeadset.STATE_DISCONNECTED) {
Log.i("[Bluetooth] Bluetooth headset disconnected");
LinphoneManager.getAudioManager().bluetoothHeadetConnectionChanged(false);
} else {
Log.w("[Bluetooth] Bluetooth headset unknown state changed: " + state);
}
} else if (action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) {
int state =
intent.getIntExtra(
BluetoothHeadset.EXTRA_STATE,
BluetoothHeadset.STATE_AUDIO_DISCONNECTED);
if (state == BluetoothHeadset.STATE_AUDIO_CONNECTED) {
Log.i("[Bluetooth] Bluetooth headset audio connected");
LinphoneManager.getAudioManager().bluetoothHeadetAudioConnectionChanged(true);
} else if (state == BluetoothHeadset.STATE_AUDIO_DISCONNECTED) {
Log.i("[Bluetooth] Bluetooth headset audio disconnected");
LinphoneManager.getAudioManager().bluetoothHeadetAudioConnectionChanged(false);
} else if (state == BluetoothHeadset.STATE_AUDIO_CONNECTING) {
Log.i("[Bluetooth] Bluetooth headset audio connecting");
} else {
Log.w("[Bluetooth] Bluetooth headset unknown audio state changed: " + state);
}
} else if (action.equals(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED)) {
int state =
intent.getIntExtra(
AudioManager.EXTRA_SCO_AUDIO_STATE,
AudioManager.SCO_AUDIO_STATE_DISCONNECTED);
if (state == AudioManager.SCO_AUDIO_STATE_CONNECTED) {
Log.i("[Bluetooth] Bluetooth headset SCO connected");
LinphoneManager.getAudioManager().bluetoothHeadetScoConnectionChanged(true);
} else if (state == AudioManager.SCO_AUDIO_STATE_DISCONNECTED) {
Log.i("[Bluetooth] Bluetooth headset SCO disconnected");
LinphoneManager.getAudioManager().bluetoothHeadetScoConnectionChanged(false);
} else if (state == AudioManager.SCO_AUDIO_STATE_CONNECTING) {
Log.i("[Bluetooth] Bluetooth headset SCO connecting");
} else if (state == AudioManager.SCO_AUDIO_STATE_ERROR) {
Log.i("[Bluetooth] Bluetooth headset SCO connection error");
} else {
Log.w("[Bluetooth] Bluetooth headset unknown SCO state changed: " + state);
}
} else if (action.equals(BluetoothHeadset.ACTION_VENDOR_SPECIFIC_HEADSET_EVENT)) {
String command =
intent.getStringExtra(BluetoothHeadset.EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD);
int type =
intent.getIntExtra(
BluetoothHeadset.EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE, -1);
String commandType;
switch (type) {
case BluetoothHeadset.AT_CMD_TYPE_ACTION:
commandType = "AT Action";
break;
case BluetoothHeadset.AT_CMD_TYPE_READ:
commandType = "AT Read";
break;
case BluetoothHeadset.AT_CMD_TYPE_TEST:
commandType = "AT Test";
break;
case BluetoothHeadset.AT_CMD_TYPE_SET:
commandType = "AT Set";
break;
case BluetoothHeadset.AT_CMD_TYPE_BASIC:
commandType = "AT Basic";
break;
default:
commandType = "AT Unknown";
break;
}
Log.i("[Bluetooth] Vendor action " + commandType + " : " + command);
} else {
Log.w("[Bluetooth] Bluetooth unknown action: " + action);
}
}
}

View file

@ -1,67 +0,0 @@
/*
* Copyright (c) 2010-2019 Belledonne Communications SARL.
*
* This file is part of linphone-android
* (see https://www.linphone.org).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.linphone.receivers;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import org.linphone.LinphoneManager;
import org.linphone.core.tools.Log;
public class HeadsetReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (isInitialStickyBroadcast()) {
Log.i("[Headset] Received broadcast from sticky cache, ignoring...");
return;
}
String action = intent.getAction();
if (action.equals(AudioManager.ACTION_HEADSET_PLUG)) {
// This happens when the user plugs a Jack headset to the device for example
// https://developer.android.com/reference/android/media/AudioManager.html#ACTION_HEADSET_PLUG
int state = intent.getIntExtra("state", 0);
String name = intent.getStringExtra("name");
int hasMicrophone = intent.getIntExtra("microphone", 0);
if (state == 0) {
Log.i("[Headset] Headset disconnected:" + name);
} else if (state == 1) {
Log.i("[Headset] Headset connected:" + name);
if (hasMicrophone == 1) {
Log.i("[Headset] Headset " + name + " has a microphone");
}
} else {
Log.w("[Headset] Unknown headset plugged state: " + state);
}
LinphoneManager.getAudioManager().routeAudioToEarPiece();
LinphoneManager.getCallManager().refreshInCallActions();
} else if (action.equals(AudioManager.ACTION_AUDIO_BECOMING_NOISY)) {
// This happens when the user disconnect a headset, so we shouldn't play audio loudly
Log.i("[Headset] Noisy state detected, most probably a headset has been disconnected");
LinphoneManager.getAudioManager().routeAudioToEarPiece();
LinphoneManager.getCallManager().refreshInCallActions();
} else {
Log.w("[Headset] Unknown action: " + action);
}
}
}

View file

@ -107,7 +107,6 @@ public class RecordingsActivity extends MainActivity
hideTopBar();
hideTabBar();
LinphoneManager.getAudioManager().setAudioManagerModeNormal();
LinphoneManager.getAudioManager().routeAudioToSpeaker();
removeDeletedRecordings();

View file

@ -20,9 +20,7 @@
package org.linphone.settings;
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.media.AudioManager;
import android.os.Bundle;
import android.text.InputType;
import android.view.LayoutInflater;
@ -274,7 +272,6 @@ public class AudioSettingsFragment extends SettingsFragment {
Core core, EcCalibratorStatus status, int delayMs) {
if (status == EcCalibratorStatus.InProgress) return;
core.removeListener(this);
LinphoneManager.getAudioManager().routeAudioToEarPiece();
if (status == EcCalibratorStatus.DoneNoEcho) {
mEchoCalibration.setSubtitle(getString(R.string.no_echo));
@ -287,12 +284,8 @@ public class AudioSettingsFragment extends SettingsFragment {
mEchoCalibration.setSubtitle(getString(R.string.failed));
}
mEchoCanceller.setChecked(status != EcCalibratorStatus.DoneNoEcho);
((AudioManager)
getActivity()
.getSystemService(Context.AUDIO_SERVICE))
.setMode(AudioManager.MODE_NORMAL);
}
});
LinphoneManager.getAudioManager().startEcCalibration();
LinphoneManager.getCore().startEchoCancellerCalibration();
}
}