Add Proximity sensing back to voice note.
This commit is contained in:
parent
ec706e95cc
commit
8a2d20403e
3 changed files with 129 additions and 14 deletions
|
@ -1,7 +1,6 @@
|
|||
package org.thoughtcrime.securesms.components.voice;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
@ -11,19 +10,14 @@ import android.os.Bundle;
|
|||
import android.os.Process;
|
||||
import android.os.RemoteException;
|
||||
import android.support.v4.media.MediaBrowserCompat;
|
||||
import android.support.v4.media.MediaDescriptionCompat;
|
||||
import android.support.v4.media.MediaMetadataCompat;
|
||||
import android.support.v4.media.session.MediaControllerCompat;
|
||||
import android.support.v4.media.session.MediaSessionCompat;
|
||||
import android.support.v4.media.session.PlaybackStateCompat;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.app.NotificationCompat;
|
||||
import androidx.core.app.NotificationManagerCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.media.MediaBrowserServiceCompat;
|
||||
import androidx.media.session.MediaButtonReceiver;
|
||||
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.DefaultLoadControl;
|
||||
|
@ -38,18 +32,10 @@ import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector;
|
|||
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
|
||||
import com.google.android.exoplayer2.ui.PlayerNotificationManager;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.color.MaterialColor;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.ContactColors;
|
||||
import org.thoughtcrime.securesms.conversation.ConversationActivity;
|
||||
import org.thoughtcrime.securesms.database.ThreadDatabase;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.notifications.NotificationChannels;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Android Service responsible for playback of voice notes.
|
||||
|
@ -74,6 +60,7 @@ public class VoiceNotePlaybackService extends MediaBrowserServiceCompat {
|
|||
private VoiceNoteNotificationManager voiceNoteNotificationManager;
|
||||
private VoiceNoteQueueDataAdapter queueDataAdapter;
|
||||
private VoiceNotePlaybackPreparer voiceNotePlaybackPreparer;
|
||||
private VoiceNoteProximityManager voiceNoteProximityManager;
|
||||
private boolean isForegroundService;
|
||||
|
||||
private final LoadControl loadControl = new DefaultLoadControl.Builder()
|
||||
|
@ -102,6 +89,7 @@ public class VoiceNotePlaybackService extends MediaBrowserServiceCompat {
|
|||
VoiceNoteMediaSourceFactory mediaSourceFactory = new VoiceNoteMediaSourceFactory(this);
|
||||
|
||||
voiceNotePlaybackPreparer = new VoiceNotePlaybackPreparer(this, player, queueDataAdapter, mediaSourceFactory);
|
||||
voiceNoteProximityManager = new VoiceNoteProximityManager(this, player);
|
||||
|
||||
mediaSession.setPlaybackState(stateBuilder.build());
|
||||
|
||||
|
@ -155,6 +143,7 @@ public class VoiceNotePlaybackService extends MediaBrowserServiceCompat {
|
|||
switch (playbackState) {
|
||||
case Player.STATE_BUFFERING:
|
||||
case Player.STATE_READY:
|
||||
voiceNoteProximityManager.onPlayerReady();
|
||||
voiceNoteNotificationManager.showNotification(player);
|
||||
|
||||
if (!playWhenReady) {
|
||||
|
@ -165,6 +154,7 @@ public class VoiceNotePlaybackService extends MediaBrowserServiceCompat {
|
|||
}
|
||||
break;
|
||||
default:
|
||||
voiceNoteProximityManager.onPlayerEnded();
|
||||
becomingNoisyReceiver.unregister();
|
||||
voiceNoteNotificationManager.hideNotification();
|
||||
}
|
||||
|
@ -184,6 +174,7 @@ public class VoiceNotePlaybackService extends MediaBrowserServiceCompat {
|
|||
@Override
|
||||
public void onPlayerError(ExoPlaybackException error) {
|
||||
Log.w(TAG, "ExoPlayer error occurred:", error);
|
||||
voiceNoteProximityManager.onPlayerError();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,119 @@
|
|||
package org.thoughtcrime.securesms.components.voice;
|
||||
|
||||
import android.content.Context;
|
||||
import android.hardware.Sensor;
|
||||
import android.hardware.SensorEvent;
|
||||
import android.hardware.SensorEventListener;
|
||||
import android.hardware.SensorManager;
|
||||
import android.media.AudioManager;
|
||||
import android.os.Build;
|
||||
import android.os.PowerManager;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.Player;
|
||||
import com.google.android.exoplayer2.SimpleExoPlayer;
|
||||
import com.google.android.exoplayer2.audio.AudioAttributes;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.util.ServiceUtil;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
class VoiceNoteProximityManager implements SensorEventListener {
|
||||
|
||||
private static final String TAG = Log.tag(VoiceNoteProximityManager.class);
|
||||
|
||||
private static final float PROXIMITY_THRESHOLD = 5f;
|
||||
|
||||
private final SimpleExoPlayer player;
|
||||
private final AudioManager audioManager;
|
||||
private final SensorManager sensorManager;
|
||||
private final Sensor proximitySensor;
|
||||
private final PowerManager.WakeLock wakeLock;
|
||||
|
||||
private long startTime;
|
||||
|
||||
VoiceNoteProximityManager(@NonNull Context context, @NonNull SimpleExoPlayer player) {
|
||||
this.player = player;
|
||||
this.audioManager = ServiceUtil.getAudioManager(context);
|
||||
this.sensorManager = ServiceUtil.getSensorManager(context);
|
||||
this.proximitySensor = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
this.wakeLock = ServiceUtil.getPowerManager(context).newWakeLock(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, TAG);
|
||||
} else {
|
||||
this.wakeLock = null;
|
||||
}
|
||||
}
|
||||
|
||||
void onPlayerReady() {
|
||||
startTime = System.currentTimeMillis();
|
||||
sensorManager.registerListener(this, proximitySensor, SensorManager.SENSOR_DELAY_NORMAL);
|
||||
}
|
||||
|
||||
void onPlayerEnded() {
|
||||
sensorManager.unregisterListener(this);
|
||||
|
||||
if (wakeLock != null && wakeLock.isHeld() && Build.VERSION.SDK_INT >= 21) {
|
||||
wakeLock.release(PowerManager.RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY);
|
||||
}
|
||||
}
|
||||
|
||||
void onPlayerError() {
|
||||
onPlayerEnded();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSensorChanged(SensorEvent event) {
|
||||
if (event.sensor.getType() != Sensor.TYPE_PROXIMITY || player.getPlaybackState() != Player.STATE_READY) {
|
||||
return;
|
||||
}
|
||||
|
||||
final int desiredStreamType;
|
||||
if (event.values[0] < PROXIMITY_THRESHOLD && event.values[0] != proximitySensor.getMaximumRange()) {
|
||||
desiredStreamType = AudioManager.STREAM_VOICE_CALL;
|
||||
} else {
|
||||
desiredStreamType = AudioManager.STREAM_MUSIC;
|
||||
}
|
||||
|
||||
final int currentStreamType = Util.getStreamTypeForAudioUsage(player.getAudioAttributes().usage);
|
||||
|
||||
if (desiredStreamType == AudioManager.STREAM_VOICE_CALL &&
|
||||
desiredStreamType != currentStreamType &&
|
||||
!audioManager.isWiredHeadsetOn())
|
||||
{
|
||||
if (wakeLock != null) {
|
||||
wakeLock.acquire(TimeUnit.MINUTES.toMillis(30));
|
||||
}
|
||||
|
||||
player.setPlayWhenReady(false);
|
||||
player.setAudioAttributes(new AudioAttributes.Builder()
|
||||
.setContentType(C.CONTENT_TYPE_SPEECH)
|
||||
.setUsage(C.USAGE_VOICE_COMMUNICATION)
|
||||
.build());
|
||||
player.setPlayWhenReady(true);
|
||||
|
||||
startTime = System.currentTimeMillis();
|
||||
} else if (desiredStreamType == AudioManager.STREAM_MUSIC &&
|
||||
desiredStreamType != currentStreamType &&
|
||||
System.currentTimeMillis() - startTime > 500)
|
||||
{
|
||||
if (wakeLock != null) {
|
||||
wakeLock.release();
|
||||
player.setPlayWhenReady(false);
|
||||
player.setAudioAttributes(new AudioAttributes.Builder()
|
||||
.setContentType(C.CONTENT_TYPE_MUSIC)
|
||||
.setUsage(C.USAGE_MEDIA)
|
||||
.build(),
|
||||
true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccuracyChanged(Sensor sensor, int accuracy) {
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@ import android.app.NotificationManager;
|
|||
import android.app.job.JobScheduler;
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.Context;
|
||||
import android.hardware.SensorManager;
|
||||
import android.hardware.display.DisplayManager;
|
||||
import android.location.LocationManager;
|
||||
import android.media.AudioManager;
|
||||
|
@ -49,6 +50,10 @@ public class ServiceUtil {
|
|||
return (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
|
||||
}
|
||||
|
||||
public static SensorManager getSensorManager(Context context) {
|
||||
return (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
|
||||
}
|
||||
|
||||
public static PowerManager getPowerManager(Context context) {
|
||||
return (PowerManager)context.getSystemService(Context.POWER_SERVICE);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue