mirror of
https://github.com/oxen-io/session-android.git
synced 2024-12-11 18:54:21 +00:00
Upgrading to the latest exoplayer: 2.19.1
This commit is contained in:
parent
90cc704016
commit
5b34a09ff9
@ -267,8 +267,8 @@ dependencies {
|
|||||||
exclude group: 'com.google.firebase', module: 'firebase-measurement-connector'
|
exclude group: 'com.google.firebase', module: 'firebase-measurement-connector'
|
||||||
}
|
}
|
||||||
if (project.hasProperty('huawei')) huaweiImplementation 'com.huawei.hms:push:6.7.0.300'
|
if (project.hasProperty('huawei')) huaweiImplementation 'com.huawei.hms:push:6.7.0.300'
|
||||||
implementation 'com.google.android.exoplayer:exoplayer-core:2.9.1'
|
implementation 'com.google.android.exoplayer:exoplayer-core:2.19.1'
|
||||||
implementation 'com.google.android.exoplayer:exoplayer-ui:2.9.1'
|
implementation 'com.google.android.exoplayer:exoplayer-ui:2.19.1'
|
||||||
implementation 'org.conscrypt:conscrypt-android:2.5.2'
|
implementation 'org.conscrypt:conscrypt-android:2.5.2'
|
||||||
implementation 'org.signal:aesgcmprovider:0.0.3'
|
implementation 'org.signal:aesgcmprovider:0.0.3'
|
||||||
implementation 'org.webrtc:google-webrtc:1.0.32006'
|
implementation 'org.webrtc:google-webrtc:1.0.32006'
|
||||||
|
@ -6,49 +6,35 @@ import android.hardware.SensorEvent;
|
|||||||
import android.hardware.SensorEventListener;
|
import android.hardware.SensorEventListener;
|
||||||
import android.hardware.SensorManager;
|
import android.hardware.SensorManager;
|
||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.os.PowerManager;
|
import android.os.PowerManager;
|
||||||
import android.os.PowerManager.WakeLock;
|
import android.os.PowerManager.WakeLock;
|
||||||
|
import android.util.Pair;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import android.util.Pair;
|
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import com.google.android.exoplayer2.C;
|
import com.google.android.exoplayer2.C;
|
||||||
import com.google.android.exoplayer2.DefaultLoadControl;
|
import com.google.android.exoplayer2.ExoPlayer;
|
||||||
import com.google.android.exoplayer2.DefaultRenderersFactory;
|
import com.google.android.exoplayer2.MediaItem;
|
||||||
import com.google.android.exoplayer2.ExoPlaybackException;
|
import com.google.android.exoplayer2.PlaybackException;
|
||||||
import com.google.android.exoplayer2.ExoPlayerFactory;
|
|
||||||
import com.google.android.exoplayer2.LoadControl;
|
|
||||||
import com.google.android.exoplayer2.PlaybackParameters;
|
import com.google.android.exoplayer2.PlaybackParameters;
|
||||||
import com.google.android.exoplayer2.Player;
|
import com.google.android.exoplayer2.Player;
|
||||||
import com.google.android.exoplayer2.SimpleExoPlayer;
|
|
||||||
import com.google.android.exoplayer2.audio.AudioAttributes;
|
import com.google.android.exoplayer2.audio.AudioAttributes;
|
||||||
import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory;
|
|
||||||
import com.google.android.exoplayer2.source.ExtractorMediaSource;
|
|
||||||
import com.google.android.exoplayer2.source.MediaSource;
|
|
||||||
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
|
|
||||||
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.thoughtcrime.securesms.attachments.AttachmentServer;
|
|
||||||
import org.session.libsignal.utilities.Log;
|
|
||||||
import org.thoughtcrime.securesms.mms.AudioSlide;
|
|
||||||
import org.session.libsession.utilities.ServiceUtil;
|
import org.session.libsession.utilities.ServiceUtil;
|
||||||
|
|
||||||
import org.session.libsession.utilities.Util;
|
import org.session.libsession.utilities.Util;
|
||||||
|
import org.session.libsignal.utilities.Log;
|
||||||
import org.session.libsignal.utilities.guava.Optional;
|
import org.session.libsignal.utilities.guava.Optional;
|
||||||
|
import org.thoughtcrime.securesms.attachments.AttachmentServer;
|
||||||
|
import org.thoughtcrime.securesms.mms.AudioSlide;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
|
|
||||||
import network.loki.messenger.BuildConfig;
|
|
||||||
import network.loki.messenger.R;
|
|
||||||
|
|
||||||
public class AudioSlidePlayer implements SensorEventListener {
|
public class AudioSlidePlayer implements SensorEventListener {
|
||||||
|
|
||||||
private static final String TAG = AudioSlidePlayer.class.getSimpleName();
|
private static final String TAG = AudioSlidePlayer.class.getSimpleName();
|
||||||
@ -64,7 +50,7 @@ public class AudioSlidePlayer implements SensorEventListener {
|
|||||||
private final @Nullable WakeLock wakeLock;
|
private final @Nullable WakeLock wakeLock;
|
||||||
|
|
||||||
private @NonNull WeakReference<Listener> listener;
|
private @NonNull WeakReference<Listener> listener;
|
||||||
private @Nullable SimpleExoPlayer mediaPlayer;
|
private @Nullable ExoPlayer mediaPlayer;
|
||||||
private @Nullable AttachmentServer audioAttachmentServer;
|
private @Nullable AttachmentServer audioAttachmentServer;
|
||||||
private long startTime;
|
private long startTime;
|
||||||
|
|
||||||
@ -111,20 +97,23 @@ public class AudioSlidePlayer implements SensorEventListener {
|
|||||||
private void play(final double progress, boolean earpiece) throws IOException {
|
private void play(final double progress, boolean earpiece) throws IOException {
|
||||||
if (this.mediaPlayer != null) { stop(); }
|
if (this.mediaPlayer != null) { stop(); }
|
||||||
|
|
||||||
LoadControl loadControl = new DefaultLoadControl.Builder().setBufferDurationsMs(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE).createDefaultLoadControl();
|
this.mediaPlayer = new ExoPlayer.Builder(context).build();
|
||||||
this.mediaPlayer = ExoPlayerFactory.newSimpleInstance(context, new DefaultRenderersFactory(context), new DefaultTrackSelector(), loadControl);
|
|
||||||
this.audioAttachmentServer = new AttachmentServer(context, slide.asAttachment());
|
this.audioAttachmentServer = new AttachmentServer(context, slide.asAttachment());
|
||||||
this.startTime = System.currentTimeMillis();
|
this.startTime = System.currentTimeMillis();
|
||||||
|
|
||||||
audioAttachmentServer.start();
|
audioAttachmentServer.start();
|
||||||
|
|
||||||
mediaPlayer.prepare(createMediaSource(audioAttachmentServer.getUri()));
|
MediaItem mediaItem = MediaItem.fromUri(audioAttachmentServer.getUri());
|
||||||
|
mediaPlayer.setMediaItem(mediaItem);
|
||||||
|
|
||||||
|
mediaPlayer.prepare();
|
||||||
mediaPlayer.setPlayWhenReady(true);
|
mediaPlayer.setPlayWhenReady(true);
|
||||||
mediaPlayer.setAudioAttributes(new AudioAttributes.Builder()
|
mediaPlayer.setAudioAttributes(new AudioAttributes.Builder()
|
||||||
.setContentType(earpiece ? C.CONTENT_TYPE_SPEECH : C.CONTENT_TYPE_MUSIC)
|
.setContentType(earpiece ? C.AUDIO_CONTENT_TYPE_SPEECH : C.AUDIO_CONTENT_TYPE_MUSIC)
|
||||||
.setUsage(earpiece ? C.USAGE_VOICE_COMMUNICATION : C.USAGE_MEDIA)
|
.setUsage(earpiece ? C.USAGE_VOICE_COMMUNICATION : C.USAGE_MEDIA)
|
||||||
.build());
|
.build(),
|
||||||
mediaPlayer.addListener(new Player.EventListener() {
|
true);
|
||||||
|
mediaPlayer.addListener(new Player.Listener() {
|
||||||
|
|
||||||
boolean started = false;
|
boolean started = false;
|
||||||
|
|
||||||
@ -187,7 +176,7 @@ public class AudioSlidePlayer implements SensorEventListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPlayerError(ExoPlaybackException error) {
|
public void onPlayerError(PlaybackException error) {
|
||||||
Log.w(TAG, "MediaPlayer Error: " + error);
|
Log.w(TAG, "MediaPlayer Error: " + error);
|
||||||
|
|
||||||
synchronized (AudioSlidePlayer.this) {
|
synchronized (AudioSlidePlayer.this) {
|
||||||
@ -213,12 +202,6 @@ public class AudioSlidePlayer implements SensorEventListener {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private MediaSource createMediaSource(@NonNull Uri uri) {
|
|
||||||
return new ExtractorMediaSource.Factory(new DefaultDataSourceFactory(context, BuildConfig.USER_AGENT))
|
|
||||||
.setExtractorsFactory(new DefaultExtractorsFactory().setConstantBitrateSeekingEnabled(true))
|
|
||||||
.createMediaSource(uri);
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void stop() {
|
public synchronized void stop() {
|
||||||
Log.i(TAG, "Stop called!");
|
Log.i(TAG, "Stop called!");
|
||||||
|
|
||||||
@ -355,7 +338,7 @@ public class AudioSlidePlayer implements SensorEventListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (streamType == AudioManager.STREAM_VOICE_CALL &&
|
if (streamType == AudioManager.STREAM_VOICE_CALL &&
|
||||||
mediaPlayer.getAudioStreamType() != streamType &&
|
mediaPlayer.getAudioAttributes().contentType != streamType &&
|
||||||
!audioManager.isWiredHeadsetOn())
|
!audioManager.isWiredHeadsetOn())
|
||||||
{
|
{
|
||||||
double position = mediaPlayer.getCurrentPosition();
|
double position = mediaPlayer.getCurrentPosition();
|
||||||
@ -370,7 +353,7 @@ public class AudioSlidePlayer implements SensorEventListener {
|
|||||||
Log.w(TAG, e);
|
Log.w(TAG, e);
|
||||||
}
|
}
|
||||||
} else if (streamType == AudioManager.STREAM_MUSIC &&
|
} else if (streamType == AudioManager.STREAM_MUSIC &&
|
||||||
mediaPlayer.getAudioStreamType() != streamType &&
|
mediaPlayer.getAudioAttributes().contentType != streamType &&
|
||||||
System.currentTimeMillis() - startTime > 500)
|
System.currentTimeMillis() - startTime > 500)
|
||||||
{
|
{
|
||||||
if (wakeLock != null) wakeLock.release();
|
if (wakeLock != null) wakeLock.release();
|
||||||
@ -411,7 +394,7 @@ public class AudioSlidePlayer implements SensorEventListener {
|
|||||||
sendEmptyMessageDelayed(0, 50);
|
sendEmptyMessageDelayed(0, 50);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isPlayerActive(@NonNull SimpleExoPlayer player) {
|
private boolean isPlayerActive(@NonNull ExoPlayer player) {
|
||||||
return player.getPlaybackState() == Player.STATE_READY || player.getPlaybackState() == Player.STATE_BUFFERING;
|
return player.getPlaybackState() == Player.STATE_READY || player.getPlaybackState() == Player.STATE_BUFFERING;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,42 +18,29 @@ package org.thoughtcrime.securesms.video;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.Window;
|
import android.view.Window;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
import android.widget.MediaController;
|
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
import android.widget.VideoView;
|
import android.widget.VideoView;
|
||||||
|
|
||||||
import com.google.android.exoplayer2.DefaultLoadControl;
|
import androidx.annotation.NonNull;
|
||||||
import com.google.android.exoplayer2.ExoPlayerFactory;
|
import androidx.annotation.Nullable;
|
||||||
import com.google.android.exoplayer2.LoadControl;
|
|
||||||
|
import com.google.android.exoplayer2.ExoPlayer;
|
||||||
|
import com.google.android.exoplayer2.MediaItem;
|
||||||
import com.google.android.exoplayer2.Player;
|
import com.google.android.exoplayer2.Player;
|
||||||
import com.google.android.exoplayer2.SimpleExoPlayer;
|
import com.google.android.exoplayer2.audio.AudioAttributes;
|
||||||
import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory;
|
|
||||||
import com.google.android.exoplayer2.extractor.ExtractorsFactory;
|
|
||||||
import com.google.android.exoplayer2.source.ExtractorMediaSource;
|
|
||||||
import com.google.android.exoplayer2.source.MediaSource;
|
|
||||||
import com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection;
|
|
||||||
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
|
|
||||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
|
||||||
import com.google.android.exoplayer2.trackselection.TrackSelector;
|
|
||||||
import com.google.android.exoplayer2.ui.PlayerControlView;
|
import com.google.android.exoplayer2.ui.PlayerControlView;
|
||||||
import com.google.android.exoplayer2.ui.PlayerView;
|
import com.google.android.exoplayer2.ui.PlayerView;
|
||||||
import com.google.android.exoplayer2.upstream.BandwidthMeter;
|
|
||||||
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
|
|
||||||
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
|
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.attachments.AttachmentServer;
|
import org.session.libsession.utilities.ViewUtil;
|
||||||
import org.session.libsignal.utilities.Log;
|
import org.session.libsignal.utilities.Log;
|
||||||
|
import org.thoughtcrime.securesms.attachments.AttachmentServer;
|
||||||
import org.thoughtcrime.securesms.mms.PartAuthority;
|
import org.thoughtcrime.securesms.mms.PartAuthority;
|
||||||
import org.thoughtcrime.securesms.mms.VideoSlide;
|
import org.thoughtcrime.securesms.mms.VideoSlide;
|
||||||
import org.session.libsession.utilities.ViewUtil;
|
|
||||||
import org.thoughtcrime.securesms.video.exo.AttachmentDataSourceFactory;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
@ -66,7 +53,7 @@ public class VideoPlayer extends FrameLayout {
|
|||||||
@Nullable private final VideoView videoView;
|
@Nullable private final VideoView videoView;
|
||||||
@Nullable private final PlayerView exoView;
|
@Nullable private final PlayerView exoView;
|
||||||
|
|
||||||
@Nullable private SimpleExoPlayer exoPlayer;
|
@Nullable private ExoPlayer exoPlayer;
|
||||||
@Nullable private PlayerControlView exoControls;
|
@Nullable private PlayerControlView exoControls;
|
||||||
@Nullable private AttachmentServer attachmentServer;
|
@Nullable private AttachmentServer attachmentServer;
|
||||||
@Nullable private Window window;
|
@Nullable private Window window;
|
||||||
@ -84,16 +71,10 @@ public class VideoPlayer extends FrameLayout {
|
|||||||
|
|
||||||
inflate(context, R.layout.video_player, this);
|
inflate(context, R.layout.video_player, this);
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= 16) {
|
this.exoView = ViewUtil.findById(this, R.id.video_view);
|
||||||
this.exoView = ViewUtil.findById(this, R.id.video_view);
|
this.videoView = null;
|
||||||
this.videoView = null;
|
this.exoControls = new PlayerControlView(getContext());
|
||||||
this.exoControls = new PlayerControlView(getContext());
|
this.exoControls.setShowTimeoutMs(-1);
|
||||||
this.exoControls.setShowTimeoutMs(-1);
|
|
||||||
} else {
|
|
||||||
this.videoView = ViewUtil.findById(this, R.id.video_view);
|
|
||||||
this.exoView = null;
|
|
||||||
initializeVideoViewControls(videoView);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setVideoSource(@NonNull VideoSlide videoSource, boolean autoplay)
|
public void setVideoSource(@NonNull VideoSlide videoSource, boolean autoplay)
|
||||||
@ -141,25 +122,20 @@ public class VideoPlayer extends FrameLayout {
|
|||||||
private void setExoViewSource(@NonNull VideoSlide videoSource, boolean autoplay)
|
private void setExoViewSource(@NonNull VideoSlide videoSource, boolean autoplay)
|
||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
|
exoPlayer = new ExoPlayer.Builder(getContext()).build();
|
||||||
TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(bandwidthMeter);
|
|
||||||
TrackSelector trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory);
|
|
||||||
LoadControl loadControl = new DefaultLoadControl();
|
|
||||||
|
|
||||||
exoPlayer = ExoPlayerFactory.newSimpleInstance(getContext(), trackSelector, loadControl);
|
|
||||||
exoPlayer.addListener(new ExoPlayerListener(window));
|
exoPlayer.addListener(new ExoPlayerListener(window));
|
||||||
|
exoPlayer.setAudioAttributes(AudioAttributes.DEFAULT, true);
|
||||||
//noinspection ConstantConditions
|
//noinspection ConstantConditions
|
||||||
exoView.setPlayer(exoPlayer);
|
exoView.setPlayer(exoPlayer);
|
||||||
//noinspection ConstantConditions
|
//noinspection ConstantConditions
|
||||||
exoControls.setPlayer(exoPlayer);
|
exoControls.setPlayer(exoPlayer);
|
||||||
|
|
||||||
DefaultDataSourceFactory defaultDataSourceFactory = new DefaultDataSourceFactory(getContext(), "GenericUserAgent", null);
|
if(videoSource.getUri() != null){
|
||||||
AttachmentDataSourceFactory attachmentDataSourceFactory = new AttachmentDataSourceFactory(getContext(), defaultDataSourceFactory, null);
|
MediaItem mediaItem = MediaItem.fromUri(videoSource.getUri());
|
||||||
ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();
|
exoPlayer.setMediaItem(mediaItem);
|
||||||
|
}
|
||||||
|
|
||||||
MediaSource mediaSource = new ExtractorMediaSource(videoSource.getUri(), attachmentDataSourceFactory, extractorsFactory, null, null);
|
exoPlayer.prepare();
|
||||||
|
|
||||||
exoPlayer.prepare(mediaSource);
|
|
||||||
exoPlayer.setPlayWhenReady(autoplay);
|
exoPlayer.setPlayWhenReady(autoplay);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,15 +165,7 @@ public class VideoPlayer extends FrameLayout {
|
|||||||
if (autoplay) this.videoView.start();
|
if (autoplay) this.videoView.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initializeVideoViewControls(@NonNull VideoView videoView) {
|
private static class ExoPlayerListener implements Player.Listener {
|
||||||
MediaController mediaController = new MediaController(getContext());
|
|
||||||
mediaController.setAnchorView(videoView);
|
|
||||||
mediaController.setMediaPlayer(videoView);
|
|
||||||
|
|
||||||
videoView.setMediaController(mediaController);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class ExoPlayerListener extends Player.DefaultEventListener {
|
|
||||||
private final Window window;
|
private final Window window;
|
||||||
|
|
||||||
ExoPlayerListener(Window window) {
|
ExoPlayerListener(Window window) {
|
||||||
|
@ -341,22 +341,6 @@
|
|||||||
<attr name="labeledEditText_textLayout" format="reference" />
|
<attr name="labeledEditText_textLayout" format="reference" />
|
||||||
</declare-styleable>
|
</declare-styleable>
|
||||||
|
|
||||||
<declare-styleable name="WaveformSeekBar">
|
|
||||||
<attr name="progress" format="float"/>
|
|
||||||
<attr name="bar_width" format="dimension"/>
|
|
||||||
<attr name="bar_gap" format="dimension"/>
|
|
||||||
<attr name="bar_min_height" format="dimension"/>
|
|
||||||
<attr name="bar_corner_radius" format="dimension"/>
|
|
||||||
<attr name="bar_background_color" format="color"/>
|
|
||||||
<attr name="bar_progress_color" format="color"/>
|
|
||||||
<!-- Corresponds to WaveformSeekBar.WaveGravity enum. -->
|
|
||||||
<attr name="bar_gravity" format="enum">
|
|
||||||
<enum name="top" value="1" />
|
|
||||||
<enum name="center" value="2" />
|
|
||||||
<enum name="bottom" value="3" />
|
|
||||||
</attr>
|
|
||||||
</declare-styleable>
|
|
||||||
|
|
||||||
<declare-styleable name="KeyboardPageSearchView">
|
<declare-styleable name="KeyboardPageSearchView">
|
||||||
<attr name="show_always" format="boolean" />
|
<attr name="show_always" format="boolean" />
|
||||||
<attr name="search_bar_tint" format="color|reference" />
|
<attr name="search_bar_tint" format="color|reference" />
|
||||||
|
@ -270,22 +270,6 @@
|
|||||||
<attr name="labeledEditText_textLayout" format="reference" />
|
<attr name="labeledEditText_textLayout" format="reference" />
|
||||||
</declare-styleable>
|
</declare-styleable>
|
||||||
|
|
||||||
<declare-styleable name="WaveformSeekBar">
|
|
||||||
<attr name="progress" format="float"/>
|
|
||||||
<attr name="bar_width" format="dimension"/>
|
|
||||||
<attr name="bar_gap" format="dimension"/>
|
|
||||||
<attr name="bar_min_height" format="dimension"/>
|
|
||||||
<attr name="bar_corner_radius" format="dimension"/>
|
|
||||||
<attr name="bar_background_color" format="color"/>
|
|
||||||
<attr name="bar_progress_color" format="color"/>
|
|
||||||
<!-- Corresponds to WaveformSeekBar.WaveGravity enum. -->
|
|
||||||
<attr name="bar_gravity" format="enum">
|
|
||||||
<enum name="top" value="1" />
|
|
||||||
<enum name="center" value="2" />
|
|
||||||
<enum name="bottom" value="3" />
|
|
||||||
</attr>
|
|
||||||
</declare-styleable>
|
|
||||||
|
|
||||||
<declare-styleable name="KeyboardPageSearchView">
|
<declare-styleable name="KeyboardPageSearchView">
|
||||||
<attr name="show_always" format="boolean" />
|
<attr name="show_always" format="boolean" />
|
||||||
<attr name="search_bar_tint" format="color|reference" />
|
<attr name="search_bar_tint" format="color|reference" />
|
||||||
|
Loading…
Reference in New Issue
Block a user