Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.provider.Settings.System.SCREEN_BRIGHTNESS;
import static android.util.Base64.URL_SAFE;
import static android.view.View.GONE;
import static android.view.View.VISIBLE;
Expand Down Expand Up @@ -50,7 +49,6 @@
import android.os.Build.VERSION_CODES;
import android.os.Bundle;
import android.os.OperationCanceledException;
import android.provider.Settings;
import android.speech.RecognitionListener;
import android.speech.RecognizerIntent;
import android.speech.SpeechRecognizer;
Expand Down Expand Up @@ -167,7 +165,8 @@ public class MainActivityDelegate extends ActivityDelegate
private FutureSupplier<?> contentLoading;
private boolean barsHidden;
private boolean videoMode;
private int brightness = 255;
private VideoView videoModeView;
private int videoBrightness = 255;
private SpeechListener speechListener;
private VoiceCommandHandler voiceCommandHandler;

Expand Down Expand Up @@ -594,32 +593,33 @@ public void setBarsHidden(boolean barsHidden) {
}

public void setVideoMode(boolean videoMode, @Nullable VideoView v) {
if (videoMode == this.videoMode) return;
if (videoMode == this.videoMode) {
if (videoMode && (v != null)) videoModeView = v;
return;
}
ControlPanelView cp = getControlPanel();

if (videoMode) {
this.videoMode = true;
videoModeView = v;
setSystemUiVisibility();
keepScreenOn(true);
cp.enableVideoMode(v);
} else {
this.videoMode = false;
videoModeView = null;
setSystemUiVisibility();
keepScreenOn(false);
if (cp != null) cp.disableVideoMode();
}

if (!checkMirroringMode(false)) {
MainActivityPrefs p = getPrefs();
boolean mirroringMode = checkMirroringMode(false);
MainActivityPrefs p = getPrefs();

if (p.getChangeBrightnessPref()) {
if (videoMode) {
brightness = getBrightness();
setBrightness(p.getBrightnessPref());
} else {
setBrightness(brightness);
}
}
if (videoMode && p.getChangeBrightnessPref()) setBrightness(p.getBrightnessPref());
else setBrightness(255);

if (!mirroringMode) {
if (p.getLandscapeVideoPref()) {
if (videoMode) {
getAppActivity().setRequestedOrientation(SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
Expand Down Expand Up @@ -655,15 +655,15 @@ public void keepScreenOn(boolean on) {
}

public int getBrightness() {
return Settings.System.getInt(getContext().getContentResolver(), SCREEN_BRIGHTNESS, 255);
return videoBrightness;
}

public void setBrightness(int br) {
try {
Settings.System.putInt(getContext().getContentResolver(), SCREEN_BRIGHTNESS, br);
} catch (SecurityException ex) {
Log.e(ex, "Failed to change brightness");
}
public void setBrightness(int brightness) {
videoBrightness = Math.max(0, Math.min(255, brightness));
VideoView videoView = videoModeView;
if (videoView == null) videoView = getMediaSessionCallback().getVideoView();
if ((videoView == null) && (body != null)) videoView = body.getVideoView();
if (videoView != null) videoView.setSoftwareBrightness(videoBrightness);
}

public boolean isVideoMode() {
Expand Down Expand Up @@ -1055,15 +1055,12 @@ public void onPreferenceChanged(PreferenceStore store, List<PreferenceStore.Pref
} else if (MainActivityPrefs.hasFullscreenPref(this, prefs)) {
setSystemUiVisibility();
} else if (prefs.contains(CHANGE_BRIGHTNESS)) {
if (getPrefs().getChangeBrightnessPref()) {
if (!Settings.System.canWrite(getContext())) {
Intent i = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS);
i.setData(Uri.parse("package:" + getContext().getPackageName()));
startActivity(i);
}
}
if (isVideoMode()) setBrightness(getPrefs().getChangeBrightnessPref() ?
getPrefs().getBrightnessPref() : 255);
} else if (prefs.contains(BRIGHTNESS)) {
if (isVideoMode()) setBrightness(getPrefs().getBrightnessPref());
if (isVideoMode() && getPrefs().getChangeBrightnessPref()) {
setBrightness(getPrefs().getBrightnessPref());
}
} else if (prefs.contains(VOICE_CONTROl_ENABLED)) {
if (!getPrefs().getVoiceControlEnabledPref()) {
getPrefs().applyBooleanPref(VOICE_CONTROl_FB, false);
Expand Down
122 changes: 119 additions & 3 deletions fermata/src/main/java/me/aap/fermata/ui/view/VideoView.java
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,19 @@
public class VideoView extends FrameLayout
implements SurfaceHolder.Callback, View.OnLayoutChangeListener, PreferenceStore.Listener,
MainActivityListener, BiConsumer<SubGrid.Position, Subtitles.Text> {
private static final int BRIGHTNESS_GESTURE_SLOP_DP = 8;
private final Set<PreferenceStore.Pref<?>> prefChange = new HashSet<>(
Arrays.asList(MediaPrefs.VIDEO_SCALE, MediaPrefs.AUDIO_DELAY, MediaPrefs.AUDIO_DELAY_AA,
MediaPrefs.SUB_DELAY));
private SubDrawer subDrawer;
private View brightnessOverlay;
private FutureSupplier<?> createSurface = new Promise<>();
private boolean brightnessGesture;
private boolean brightnessDragging;
private float brightnessStartX;
private float brightnessStartY;
private int brightnessStartValue;
private int brightnessGestureValue;

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gesture detection is already implemented in ControlPanelView.onScroll()


public VideoView(Context context) {
this(context, null);
Expand Down Expand Up @@ -127,11 +135,22 @@ protected void init(Context context) {
});

addInfoView(context);
addBrightnessOverlay(context);
addOnLayoutChangeListener(this);
setLayoutParams(new CircularRevealFrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT));
setFocusable(true);
}

protected void addBrightnessOverlay(Context context) {
brightnessOverlay = new View(context);
brightnessOverlay.setBackgroundColor(Color.BLACK);
brightnessOverlay.setAlpha(0f);
brightnessOverlay.setClickable(false);
brightnessOverlay.setFocusable(false);
brightnessOverlay.setVisibility(GONE);
addView(brightnessOverlay, new FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT));
}

protected void addInfoView(Context context) {
VideoInfoView d = new VideoInfoView(context, null);
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT);
Expand Down Expand Up @@ -199,6 +218,7 @@ public void showVideo(boolean hideTitle) {
createSurface.onSuccess(v -> {
MainActivityDelegate a = getActivity().peek();
if (a == null) return;
if (a.getPrefs().getChangeBrightnessPref()) setSoftwareBrightness(a.getBrightness());
MediaSessionCallback cb = a.getMediaSessionCallback();
MediaEngine eng = cb.getEngine();
if (eng != null) setSurfaceSize(eng);
Expand All @@ -207,6 +227,15 @@ public void showVideo(boolean hideTitle) {
});
}

public void setSoftwareBrightness(int brightness) {
View overlay = brightnessOverlay;
if (overlay == null) return;
int value = Math.max(0, Math.min(255, brightness));
float alpha = (255 - value) / 255f;
overlay.setAlpha(alpha);
overlay.setVisibility(alpha == 0f ? GONE : VISIBLE);
}

public void prepareSubDrawer(boolean dbl) {
MainActivityDelegate a = getActivity().peek();
if (a == null) return;
Expand Down Expand Up @@ -396,9 +425,96 @@ public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width,

@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouchEvent(@NonNull MotionEvent e) {
MainActivityDelegate a = getActivity().peek();
return (a != null) && a.interceptTouchEvent(e, this::onTouch);
public boolean onTouchEvent(@NonNull MotionEvent event) {
if (handleBrightnessGesture(event)) return true;
MainActivityDelegate activity = getActivity().peek();
return (activity != null) && activity.interceptTouchEvent(event, this::onTouch);
}

public boolean handleBrightnessGesture(@NonNull MotionEvent event) {
MainActivityDelegate activity = getActivity().peek();
if (activity == null) return false;

switch (event.getActionMasked()) {
case MotionEvent.ACTION_POINTER_DOWN -> {
if (event.getPointerCount() == 2) {
brightnessGesture = true;
brightnessDragging = false;
brightnessStartX = getPointerCenterX(event);
brightnessStartY = getPointerCenterY(event);
brightnessStartValue = activity.getBrightness();
brightnessGestureValue = brightnessStartValue;
} else {
resetBrightnessGesture();
}
}
case MotionEvent.ACTION_MOVE -> {
if (!brightnessGesture || (event.getPointerCount() < 2)) return false;

float currentX = getPointerCenterX(event);
float currentY = getPointerCenterY(event);
float deltaX = currentX - brightnessStartX;
float deltaY = currentY - brightnessStartY;

if (!brightnessDragging) {
int slop = toIntPx(getContext(), BRIGHTNESS_GESTURE_SLOP_DP);
if (Math.abs(deltaY) < slop) return false;
if (Math.abs(deltaX) > Math.abs(deltaY)) {
resetBrightnessGesture();
return false;
}

brightnessDragging = true;
if (!activity.getPrefs().getChangeBrightnessPref()) {
activity.getPrefs().applyBooleanPref(
MainActivityPrefs.CHANGE_BRIGHTNESS, true);
}
}

int height = getHeight();
if ((height <= 0) && (getParent() instanceof View parent)) {
height = parent.getHeight();
}
int travel = Math.max(height / 2, 1);
int value = brightnessStartValue - Math.round(deltaY * 255f / travel);
brightnessGestureValue = Math.max(0, Math.min(255, value));
activity.setBrightness(brightnessGestureValue);
setSoftwareBrightness(activity.getBrightness());
return true;
}
case MotionEvent.ACTION_POINTER_UP, MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
boolean handled = brightnessDragging;
if (handled) activity.getPrefs().applyIntPref(
MainActivityPrefs.BRIGHTNESS, brightnessGestureValue);
resetBrightnessGesture();
return handled;
}
}

return false;
}

private void resetBrightnessGesture() {
brightnessGesture = false;
brightnessDragging = false;
}

private static float getPointerCenterX(@NonNull MotionEvent event) {
float center = 0f;
int pointerCount = Math.min(event.getPointerCount(), 2);
for (int pointerIndex = 0; pointerIndex < pointerCount; pointerIndex++) {
center += event.getX(pointerIndex);
}
return center / pointerCount;
}

private static float getPointerCenterY(@NonNull MotionEvent event) {
float center = 0f;
int pointerCount = Math.min(event.getPointerCount(), 2);
for (int pointerIndex = 0; pointerIndex < pointerCount; pointerIndex++) {
center += event.getY(pointerIndex);
}
return center / pointerCount;
}

@Override
Expand Down
4 changes: 2 additions & 2 deletions fermata/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -344,9 +344,9 @@
<string name="clock_pos_left">Left</string>
<string name="clock_pos_right">Right</string>
<string name="clock_pos_center">Center</string>
<string name="change_brightness">Change brightness while playing video</string>
<string name="change_brightness">Dim video while playing</string>
<string name="video_brightness">Video brightness</string>
<string name="change_brightness_sub">The brightness can also be changed with two finger scroll</string>
<string name="change_brightness_sub">Uses a software overlay and can also be adjusted with two-finger vertical scroll</string>
<string name="watched_threshold">Watched threshold</string>
<string name="watched_threshold_sub">Marked video as watched, if more than this number of percentages has been watched</string>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@
import android.content.Context;
import android.util.AttributeSet;
import android.view.SurfaceView;
import android.view.View;
import android.widget.FrameLayout;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import me.aap.fermata.addon.web.R;
import me.aap.fermata.ui.activity.MainActivityDelegate;
import me.aap.fermata.ui.view.VideoInfoView;
import me.aap.fermata.ui.view.VideoView;

Expand All @@ -26,6 +29,7 @@ public YoutubeVideoView(Context context, AttributeSet attrs) {
protected void init(Context context) {
addView(new FrameLayout(context), new FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT));
addInfoView(context);
addBrightnessOverlay(context);
}

@NonNull
Expand All @@ -39,4 +43,15 @@ public VideoInfoView getVideoInfoView() {
public SurfaceView getSubtitleSurface() {
return null;
}

@Override
public void setSoftwareBrightness(int brightness) {
super.setSoftwareBrightness(brightness);
View overlay = MainActivityDelegate.get(getContext()).findViewById(R.id.ytBrightnessOverlay);
if (overlay == null) return;
int value = Math.max(0, Math.min(255, brightness));
float alpha = (255 - value) / 255f;
overlay.setAlpha(alpha);
overlay.setVisibility(alpha == 0f ? View.GONE : View.VISIBLE);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,21 @@

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.webkit.CookieManager;

import androidx.annotation.NonNull;

import java.util.List;

import me.aap.fermata.BuildConfig;
import me.aap.fermata.addon.web.R;
import me.aap.fermata.addon.web.FermataChromeClient;
import me.aap.fermata.addon.web.FermataJsInterface;
import me.aap.fermata.addon.web.FermataWebView;
import me.aap.fermata.media.service.MediaSessionCallback;
import me.aap.fermata.ui.activity.MainActivityDelegate;
import me.aap.fermata.ui.view.VideoView;
import me.aap.utils.async.FutureSupplier;
import me.aap.utils.async.Promise;
import me.aap.utils.log.Log;
Expand Down Expand Up @@ -90,6 +93,13 @@ public void goBack() {
super.goBack();
}

@Override
public boolean onTouchEvent(MotionEvent event) {
VideoView videoView = MainActivityDelegate.get(getContext()).findViewById(R.id.ytVideoView);
if ((videoView != null) && videoView.handleBrightnessGesture(event)) return true;
return super.onTouchEvent(event);
}

@Override
protected void pageLoaded(String uri) {
attachListeners();
Expand Down
10 changes: 10 additions & 0 deletions modules/web/src/main/res/layout/youtube.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,16 @@
android:layout_width="match_parent"
android:layout_height="match_parent" />

<View
android:id="@+id/ytBrightnessOverlay"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:alpha="0"
android:background="#000000"
android:clickable="false"
android:focusable="false"
android:visibility="gone" />

<me.aap.fermata.addon.web.yt.YoutubeVideoView
android:id="@+id/ytVideoView"
android:layout_width="match_parent"
Expand Down
Loading