Skip to content

Commit

Permalink
Added web browser User-Agent settings. Fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
AndreyPavlenko committed May 24, 2021
1 parent 0db323d commit 36d42d5
Show file tree
Hide file tree
Showing 10 changed files with 140 additions and 92 deletions.
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
ext {
def abi = project.properties['ABI']
VERSION_CODE = 90
VERSION_NAME = "1.7.9"
VERSION_CODE = 91
VERSION_NAME = "1.7.10"
SDK_MIN_VERSION = 23
SDK_TARGET_VERSION = 30
SDK_COMPILE_VERSION = 30
Expand Down
4 changes: 3 additions & 1 deletion fermata/src/main/java/me/aap/fermata/ui/view/BodyLayout.java
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ public void setMode(Mode mode) {
getSplitHandle().setVisibility(GONE);
getSwipeRefresh().setVisibility(GONE);
lp.guidePercent = isPortrait() ? 1f : 0f;
vv.showVideo();
vv.showVideo(true);
getActivity().setVideoMode(true, vv);
App.get().getHandler().post(vv::requestFocus);
break;
Expand All @@ -98,6 +98,7 @@ public void setMode(Mode mode) {
getSplitHandle().setVisibility(VISIBLE);
getSwipeRefresh().setVisibility(VISIBLE);
lp.guidePercent = getActivity().getPrefs().getSplitPercent(getContext());
vv.showVideo(true);
getActivity().setVideoMode(false, vv);
break;
}
Expand Down Expand Up @@ -196,6 +197,7 @@ public void onPlayableChanged(MediaLib.PlayableItem oldItem, MediaLib.PlayableIt
setMode(BodyLayout.Mode.FRAME);
} else {
if (isFrameMode()) setMode(BodyLayout.Mode.VIDEO);
else getVideoView().showVideo(false);
}
}

Expand Down
39 changes: 18 additions & 21 deletions fermata/src/main/java/me/aap/fermata/ui/view/VideoView.java
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,16 @@ protected void init(Context context) {
getHolder().addCallback(VideoView.this);
}
});
addView(new SurfaceView(getContext()) {
{
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT);
lp.gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
setLayoutParams(lp);
setZOrderMediaOverlay(true);
getHolder().setFormat(PixelFormat.TRANSLUCENT);
getHolder().addCallback(VideoView.this);
}
});

addTitle(context);
setLayoutParams(new CircularRevealFrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT));
Expand All @@ -93,30 +103,15 @@ public SurfaceView getVideoSurface() {
return (SurfaceView) getChildAt(0);
}

public SurfaceView getSubtitleSurface(boolean create) {
if (getChildCount() < 3) {
if (!create) return null;
removeViewAt(1);
Context ctx = getContext();
SurfaceView v = new SurfaceView(ctx);
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT);
lp.gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
v.setLayoutParams(lp);
v.setZOrderMediaOverlay(true);
v.getHolder().setFormat(PixelFormat.TRANSLUCENT);
addView(v);
addTitle(ctx);
return v;
}

return (SurfaceView) getChildAt(1);
public SurfaceView getSubtitleSurface() {
return (getChildCount() < 3) ? null : (SurfaceView) getChildAt(1);
}

public TextView getTitle() {
return (TextView) getChildAt((getChildCount() < 3) ? 1 : 2);
}

public void showVideo() {
public void showVideo(boolean hideTitle) {
if (surfaceCreated) {
MainActivityDelegate a = getActivity();
MediaSessionCallback cb = a.getMediaSessionCallback();
Expand All @@ -130,7 +125,7 @@ public void showVideo() {
cb.addVideoView(this, a.isCarActivity() ? 0 : 1);

TextView title = getTitle();
title.setVisibility(GONE);
if (hideTitle) title.setVisibility(GONE);

i.getMediaDescription().main().onSuccess(dsc -> {
if (cb.getCurrentItem() != i) return;
Expand Down Expand Up @@ -203,7 +198,7 @@ public void setSurfaceSize(MediaEngine eng) {
surface.setLayoutParams(lp);
}

if ((surface = getSubtitleSurface(false)) != null) {
if ((surface = getSubtitleSurface()) != null) {
lp = surface.getLayoutParams();

if ((lp.width != width) || (lp.height != height)) {
Expand All @@ -230,8 +225,10 @@ public void onLayoutChange(View v, int left, int top, int right, int bottom, int

@Override
public void surfaceCreated(@NonNull SurfaceHolder holder) {
if(!getVideoSurface().getHolder().getSurface().isValid()) return;
if(!getSubtitleSurface().getHolder().getSurface().isValid()) return;
surfaceCreated = true;
showVideo();
showVideo(true);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
import com.google.android.exoplayer2.util.Util;
import com.google.android.exoplayer2.video.VideoListener;
import com.google.android.exoplayer2.video.VideoSize;

import me.aap.fermata.BuildConfig;
import me.aap.fermata.media.engine.AudioEffects;
Expand All @@ -35,7 +35,7 @@
/**
* @author Andrey Pavlenko
*/
public class ExoPlayerEngine implements MediaEngine, Player.EventListener, VideoListener {
public class ExoPlayerEngine implements MediaEngine, Player.Listener {
private final Context ctx;
private final Listener listener;
private final SimpleExoPlayer player;
Expand Down Expand Up @@ -190,8 +190,8 @@ public void onPlaybackStateChanged(int playbackState) {
}

@Override
public void onVideoSizeChanged(int width, int height, int unappliedRotationDegrees, float pixelWidthHeightRatio) {
listener.onVideoSizeChanged(this, width, height);
public void onVideoSizeChanged(VideoSize videoSize) {
listener.onVideoSizeChanged(this, videoSize.width, videoSize.height);
}

@Override
Expand Down
39 changes: 5 additions & 34 deletions modules/vlc/src/main/java/me/aap/fermata/engine/vlc/VlcEngine.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import android.media.AudioManager;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.ViewGroup;

Expand Down Expand Up @@ -54,7 +53,7 @@
/**
* @author Andrey Pavlenko
*/
public class VlcEngine implements MediaEngine, MediaPlayer.EventListener, SurfaceHolder.Callback,
public class VlcEngine implements MediaEngine, MediaPlayer.EventListener,
IVLCVout.OnNewVideoLayoutListener {
@SuppressWarnings({"FieldCanBeLocal", "unused"}) // Hold reference to prevent garbage collection
private final VlcEngineProvider provider;
Expand Down Expand Up @@ -102,7 +101,7 @@ public void prepare(PlayableItem source) {
} else {
media = new Media(vlc, uri);

if (scheme.startsWith("http")) {
if ((scheme != null) && scheme.startsWith("http")) {
String agent = source.getUserAgent();
if (agent != null) media.addOption(":http-user-agent='" + agent + "'");
}
Expand Down Expand Up @@ -224,17 +223,13 @@ public void setSpeed(float speed) {

@Override
public void setVideoView(VideoView view) {
if (this.videoView != null) {
this.videoView.getVideoSurface().getHolder().removeCallback(this);
}

this.videoView = view;
IVLCVout out = player.getVLCVout();
out.detachViews();

if (view != null) {
out.setVideoView(view.getVideoSurface());
out.setSubtitlesView(view.getSubtitleSurface(true));
out.setSubtitlesView(view.getSubtitleSurface());
out.attachViews(this);
setSurfaceSize(view);
}
Expand Down Expand Up @@ -330,12 +325,7 @@ public void setSubtitleDelay(int milliseconds) {
@Override
public void close() {
stop();

if (videoView != null) {
videoView.getVideoSurface().getHolder().removeCallback(this);
videoView = null;
}

videoView = null;
player.release();
if (effects != null) effects.release();
}
Expand All @@ -355,16 +345,6 @@ public void onEvent(MediaPlayer.Event event) {
}
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
if ((videoView == null) || !(source instanceof VideoSource)) return;
setSurfaceSize(videoView, (VideoSource) source);
}

@Override
public void onNewVideoLayout(IVLCVout vlcVout, int width, int height, int visibleWidth,
int visibleHeight, int sarNum, int sarDen) {
Expand Down Expand Up @@ -517,7 +497,7 @@ private void setSurfaceLayout(VideoView view, int width, int height) {
surface.setLayoutParams(lp);
}

if ((surface = view.getSubtitleSurface(false)) != null) {
if ((surface = view.getSubtitleSurface()) != null) {
lp = surface.getLayoutParams();

if ((lp.width != width) || (lp.height != height)) {
Expand All @@ -528,15 +508,6 @@ private void setSurfaceLayout(VideoView view, int width, int height) {
}
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
if ((videoView != null) && (videoView.getVideoSurface().getHolder() == holder)) {
holder.removeCallback(this);
videoView = null;
player.getVLCVout().detachViews();
}
}

private void startPlaying() {
playing = true;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@
import me.aap.utils.ui.view.TextChangedListener;
import me.aap.utils.ui.view.ToolBarView;

import static android.os.Build.VERSION;
import static android.os.Build.VERSION_CODES;
import static androidx.webkit.WebViewFeature.FORCE_DARK;
import static java.util.Objects.requireNonNull;
import static me.aap.fermata.addon.web.FermataJsInterface.JS_EDIT;
import static me.aap.fermata.addon.web.FermataJsInterface.JS_EVENT;

Expand Down Expand Up @@ -74,40 +77,49 @@ public void init(WebBrowserAddon addon, FermataWebClient webClient, FermataChrom
s.setJavaScriptEnabled(true);
s.setJavaScriptCanOpenWindowsAutomatically(true);

setDesktopMode(addon.isDesktopVersion(), false);
addon.getPreferenceStore().addBroadcastListener(this);
addJavascriptInterface(createJsInterface(), FermataJsInterface.NAME);
CookieManager.getInstance().setAcceptThirdPartyCookies(this, true);

if (WebViewFeature.isFeatureSupported(FORCE_DARK)) {
if (addon.isForceDark()) {
WebSettingsCompat.setForceDark(s, WebSettingsCompat.FORCE_DARK_ON);
}
}
addon.getPreferenceStore().addBroadcastListener(this);
setDesktopMode(addon, false);
setForceDark(addon, false);
}

@Override
public void onPreferenceChanged(PreferenceStore store, List<PreferenceStore.Pref<?>> prefs) {
WebBrowserAddon addon = getAddon();

if ((addon != null) && prefs.contains(addon.getDesktopVersionPref())) {
setDesktopMode(store.getBooleanPref(addon.getDesktopVersionPref()), true);
WebBrowserAddon a = getAddon();
if (a == null) return;

if (prefs.contains(a.getDesktopVersionPref())) {
setDesktopMode(a, true);
} else if (prefs.contains(a.getUserAgentPref())) {
UserAgent.ua = null;
setDesktopMode(a, true);
} else if (prefs.contains(a.getUserAgentDesktopPref())) {
UserAgent.uaDesktop = null;
setDesktopMode(a, true);
} else if (prefs.contains(a.getForceDarkPref())) {
setForceDark(addon, true);
}
}

private void setDesktopMode(boolean v, boolean reload) {
private void setDesktopMode(WebBrowserAddon a, boolean reload) {
if (getClass() != FermataWebView.class) return;

WebSettings s = getSettings();
boolean v = a.getPreferenceStore().getBooleanPref(a.getDesktopVersionPref());
String ua = v ? UserAgent.getUaDesktop(s, a) : UserAgent.getUa(s, a);
Log.d("Setting User-Agent to " + ua);
s.setUserAgentString(ua);
s.setUseWideViewPort(v);
if (reload) reload();
}

if (v) {
String ua = UserAgent.getPc(s);
Log.d("Changing UserAgent to " + ua);
s.setUserAgentString(ua);
} else {
s.setUserAgentString(null);
private void setForceDark(WebBrowserAddon a, boolean reload) {
if (WebViewFeature.isFeatureSupported(FORCE_DARK)) {
int v = a.isForceDark() ? WebSettingsCompat.FORCE_DARK_ON : WebSettingsCompat.FORCE_DARK_AUTO;
WebSettingsCompat.setForceDark(getSettings(), v);
}

if (reload) reload();
}

protected FermataJsInterface createJsInterface() {
Expand Down Expand Up @@ -290,30 +302,58 @@ public boolean onInterceptTouchEvent(MotionEvent ev) {
return super.onInterceptTouchEvent(ev);
}

private static final class UserAgent {
private static String pc;
static final class UserAgent {
private static final Pattern pattern = Pattern.compile(".+ AppleWebKit/(\\S+) .+ Chrome/(\\S+) .+");
static String ua;
static String uaDesktop;

static String getUa(WebSettings s, WebBrowserAddon a) {
if (ua != null) return ua;

String ua = s.getUserAgentString();
Matcher m = pattern.matcher(ua);

if (m.matches()) {
String av;
if (VERSION.SDK_INT >= VERSION_CODES.R) av = VERSION.RELEASE_OR_CODENAME;
else av = VERSION.RELEASE;
String wv = m.group(1);
String cv = m.group(2);
UserAgent.ua = a.getPreferenceStore().getStringPref(a.getUserAgentPref()).trim()
.replace("{ANDROID_VERSION}", av)
.replace("{WEBKIT_VERSION}", requireNonNull(wv))
.replace("{CHROME_VERSION}", requireNonNull(cv));
if (UserAgent.ua.isEmpty()) UserAgent.ua = ua;
} else {
Log.w("User-Agent does not match the pattern ", pattern, ": " + ua);
UserAgent.ua = ua;
}

return UserAgent.ua;
}

static String getPc(WebSettings s) {
if (pc != null) return pc;
static String getUaDesktop(WebSettings s, WebBrowserAddon a) {
if (uaDesktop != null) return uaDesktop;

String ua = s.getUserAgentString();
Pattern pattern = Pattern.compile(".+ AppleWebKit/(\\S+) .+ Chrome/(\\S+) .+");
Matcher m = pattern.matcher(ua);

if (m.matches()) {
String wv = m.group(1);
String cv = m.group(2);
pc = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/" + wv
+ " (KHTML, like Gecko) Chrome/" + cv + " Safari/" + wv;
uaDesktop = a.getPreferenceStore().getStringPref(a.getUserAgentDesktopPref())
.replace("{WEBKIT_VERSION}", requireNonNull(wv))
.replace("{CHROME_VERSION}", requireNonNull(cv));
} else {
Log.w("User-Agent does not match the pattern ", pattern, ": " + ua);
int i1 = ua.indexOf('(') + 1;
int i2 = ua.indexOf(')', i1);
pc = ua.substring(0, i1) + "X11; Linux x86_64" + ua.substring(i2)
uaDesktop = ua.substring(0, i1) + "X11; Linux x86_64" + ua.substring(i2)
.replace(" Mobile ", " ")
.replaceFirst(" Version/\\d+\\.\\d+ ", " ");
}

return pc;
return uaDesktop;
}
}
}
Loading

0 comments on commit 36d42d5

Please sign in to comment.