Skip to content

Commit 7cb8f3c

Browse files
committed
feat:
1 parent 5c2c34a commit 7cb8f3c

9 files changed

Lines changed: 134 additions & 5 deletions

File tree

‎app/build.gradle‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ android {
1515
minSdk 28
1616
targetSdk 36
1717
versionCode 2
18-
versionName "0.7"
19-
buildConfigField "boolean", "IS_BETA", "false"
18+
versionName "0.7.1"
19+
buildConfigField "boolean", "IS_BETA", "true"
2020

2121
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
2222

‎app/src/main/java/com/drivehub/kamera/MainActivity.java‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,8 @@ private void showSettingsDialog() {
197197
SharedPreferences avmPrefs = getSharedPreferences(AVM_PREFS_NAME, MODE_PRIVATE);
198198

199199
Switch swOverlay = dialog.findViewById(R.id.switchOverlayOnSignal);
200+
Switch swRotateToDrivingDirection =
201+
dialog.findViewById(R.id.switchOverlayRotateToDrivingDirection);
200202
Switch swSafetyWarning = dialog.findViewById(R.id.switchSafetyWarning);
201203
swSafetyWarning.setChecked(avmPrefs.getBoolean(KEY_SAFETY_WARNING, true));
202204
swSafetyWarning.setOnCheckedChangeListener((btn, checked) -> {
@@ -233,6 +235,7 @@ private void showSettingsDialog() {
233235
signalCameraSettingsController.bind(
234236
prefs,
235237
swOverlay,
238+
swRotateToDrivingDirection,
236239
seekOverlayHideDelay,
237240
etOverlayHideDelayValue,
238241
seekOverlayMinShow,
@@ -248,6 +251,7 @@ private void showSettingsDialog() {
248251
appearanceController.bindSettingsAppearance(
249252
prefs,
250253
swOverlay,
254+
swRotateToDrivingDirection,
251255
swSafetyWarning,
252256
swAllowBetaUpdates,
253257
dialogClose,

‎app/src/main/java/com/drivehub/kamera/OverlayService.java‎

Lines changed: 84 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ public class OverlayService extends Service implements TextureView.SurfaceTextur
7272
(sharedPreferences, key) -> {
7373
if (UiPrefs.KEY_TILE_CORNER_RADIUS.equals(key)) {
7474
applyOverlayCornerRadius();
75+
} else if (UiPrefs.KEY_OVERLAY_ROTATE_TO_DRIVING_DIRECTION.equals(key)) {
76+
updateOverlayPresentation(true);
7577
}
7678
};
7779

@@ -114,6 +116,7 @@ public int onStartCommand(Intent intent, int flags, int startId) {
114116
showFloatingWindow();
115117
} else {
116118
applyOverlayCornerRadius();
119+
updateOverlayPresentation(false);
117120
// If the overlay is already open and only the camera index changed, switch the feed.
118121
if (textureSurface != null && textureSurface.isValid()) {
119122
startPreview();
@@ -139,6 +142,7 @@ private void showFloatingWindow() {
139142
}
140143
} catch (Throwable ignored) {
141144
}
145+
normalizeOverlaySizeForCurrentMode();
142146

143147
overlayParams = new WindowManager.LayoutParams(
144148
overlayWidthPx,
@@ -181,6 +185,7 @@ public boolean onScale(ScaleGestureDetector detector) {
181185
overlayParams.height = overlayHeightPx;
182186
clampOverlayPositionToScreen();
183187
windowManager.updateViewLayout(overlayView, overlayParams);
188+
applyPreviewTransform();
184189
return true;
185190
}
186191

@@ -191,6 +196,7 @@ public void onScaleEnd(ScaleGestureDetector detector) {
191196
});
192197

193198
windowManager.addView(overlayView, overlayParams);
199+
applyPreviewTransform();
194200

195201
overlayView.setOnTouchListener((v, event) -> {
196202
// Two fingers: pinch to resize, with no dragging.
@@ -299,9 +305,9 @@ private int dpToPx(int dp) {
299305
return Math.round(dp * getResources().getDisplayMetrics().density);
300306
}
301307

302-
/** Keeps the 1000:480 aspect ratio while clamping size to screen and min/max bounds. */
308+
/** Keeps the active overlay aspect ratio while clamping size to screen and min/max bounds. */
303309
private int[] clampOverlaySize(int w) {
304-
float aspect = (float) DEFAULT_OVERLAY_WIDTH_PX / (float) DEFAULT_OVERLAY_HEIGHT_PX;
310+
float aspect = getActiveOverlayAspect();
305311
int maxW = OVERLAY_MAX_WIDTH_PX;
306312
int maxH = OVERLAY_MAX_WIDTH_PX;
307313
int[] screenSize = getAvailableScreenSizePx();
@@ -330,6 +336,79 @@ private int[] clampOverlaySize(int w) {
330336
return new int[]{w, h};
331337
}
332338

339+
private void normalizeOverlaySizeForCurrentMode() {
340+
boolean shouldRotate = shouldRotatePreviewToDrivingDirection();
341+
boolean isLandscape = overlayWidthPx >= overlayHeightPx;
342+
if (shouldRotate == isLandscape) {
343+
int swappedWidth = overlayHeightPx;
344+
overlayHeightPx = overlayWidthPx;
345+
overlayWidthPx = swappedWidth;
346+
}
347+
int[] clamped = clampOverlaySize(overlayWidthPx);
348+
overlayWidthPx = clamped[0];
349+
overlayHeightPx = clamped[1];
350+
}
351+
352+
private float getActiveOverlayAspect() {
353+
return shouldRotatePreviewToDrivingDirection()
354+
? (float) DEFAULT_OVERLAY_HEIGHT_PX / (float) DEFAULT_OVERLAY_WIDTH_PX
355+
: (float) DEFAULT_OVERLAY_WIDTH_PX / (float) DEFAULT_OVERLAY_HEIGHT_PX;
356+
}
357+
358+
private boolean shouldRotatePreviewToDrivingDirection() {
359+
return uiPrefs != null
360+
&& UiPrefs.isOverlayRotationToDrivingDirectionEnabled(uiPrefs)
361+
&& (cameraIndex == 14 || cameraIndex == 16);
362+
}
363+
364+
private float getPreviewRotationDegrees() {
365+
if (!shouldRotatePreviewToDrivingDirection()) {
366+
return 0f;
367+
}
368+
return cameraIndex == 16 ? -90f : 90f;
369+
}
370+
371+
private void updateOverlayPresentation(boolean persist) {
372+
normalizeOverlaySizeForCurrentMode();
373+
if (overlayParams != null) {
374+
overlayParams.width = overlayWidthPx;
375+
overlayParams.height = overlayHeightPx;
376+
clampOverlayPositionToScreen();
377+
if (windowManager != null && overlayView != null) {
378+
windowManager.updateViewLayout(overlayView, overlayParams);
379+
}
380+
}
381+
applyPreviewTransform();
382+
if (persist) {
383+
saveOverlayLayoutPrefs();
384+
}
385+
}
386+
387+
private void applyPreviewTransform() {
388+
if (textureView == null) return;
389+
textureView.post(() -> {
390+
if (textureView == null) return;
391+
FrameLayout.LayoutParams params;
392+
if (shouldRotatePreviewToDrivingDirection()) {
393+
params = new FrameLayout.LayoutParams(
394+
overlayHeightPx,
395+
overlayWidthPx,
396+
Gravity.CENTER
397+
);
398+
} else {
399+
params = new FrameLayout.LayoutParams(
400+
ViewGroup.LayoutParams.MATCH_PARENT,
401+
ViewGroup.LayoutParams.MATCH_PARENT,
402+
Gravity.CENTER
403+
);
404+
}
405+
textureView.setLayoutParams(params);
406+
textureView.setScaleX(1f);
407+
textureView.setScaleY(1f);
408+
textureView.setRotation(getPreviewRotationDegrees());
409+
});
410+
}
411+
333412
private void clampOverlayPositionToScreen() {
334413
if (windowManager == null || overlayParams == null) return;
335414
int[] screenSize = getAvailableScreenSizePx();
@@ -413,12 +492,13 @@ public IBinder onBind(Intent intent) {
413492
@Override
414493
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
415494
textureSurface = new Surface(surface);
495+
applyPreviewTransform();
416496
startPreview();
417497
}
418498

419499
@Override
420500
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
421-
// no-op
501+
applyPreviewTransform();
422502
}
423503

424504
@Override
@@ -440,6 +520,7 @@ private void startPreview() {
440520
if (textureSurface == null || !textureSurface.isValid()) {
441521
return;
442522
}
523+
applyPreviewTransform();
443524
CameraProbe.stopPreview();
444525
CameraProbe.startPreview(cameraIndex, textureSurface);
445526
}

‎app/src/main/java/com/drivehub/kamera/SettingsAppearanceController.java‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ final class SettingsAppearanceController {
2727
private boolean isNormalizingAccentColor;
2828
private SharedPreferences prefs;
2929
private Switch swOverlay;
30+
private Switch swRotateToDrivingDirection;
3031
private Switch swSafetyWarning;
3132
private Switch swAllowBetaUpdates;
3233
private ImageButton dialogClose;
@@ -59,6 +60,7 @@ void applyMainUiIconColors() {
5960
void bindSettingsAppearance(
6061
SharedPreferences prefs,
6162
Switch swOverlay,
63+
Switch swRotateToDrivingDirection,
6264
Switch swSafetyWarning,
6365
Switch swAllowBetaUpdates,
6466
ImageButton dialogClose,
@@ -78,6 +80,7 @@ void bindSettingsAppearance(
7880
) {
7981
this.prefs = prefs;
8082
this.swOverlay = swOverlay;
83+
this.swRotateToDrivingDirection = swRotateToDrivingDirection;
8184
this.swSafetyWarning = swSafetyWarning;
8285
this.swAllowBetaUpdates = swAllowBetaUpdates;
8386
this.dialogClose = dialogClose;
@@ -291,6 +294,9 @@ private void applyAccentColorToSettingsDialog(int accentColor) {
291294
if (swOverlay != null) {
292295
swOverlay.setTrackTintList(buildToggleTrackTint(accentColor));
293296
}
297+
if (swRotateToDrivingDirection != null) {
298+
swRotateToDrivingDirection.setTrackTintList(buildToggleTrackTint(accentColor));
299+
}
294300
if (swSafetyWarning != null) {
295301
swSafetyWarning.setTrackTintList(buildToggleTrackTint(accentColor));
296302
}

‎app/src/main/java/com/drivehub/kamera/SignalCameraSettingsController.java‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ final class SignalCameraSettingsController {
1919
void bind(
2020
SharedPreferences prefs,
2121
Switch swOverlay,
22+
Switch swRotateToDrivingDirection,
2223
SeekBar seekOverlayHideDelay,
2324
EditText etOverlayHideDelayValue,
2425
SeekBar seekOverlayMinShow,
@@ -34,6 +35,17 @@ void bind(
3435
});
3536
}
3637

38+
if (swRotateToDrivingDirection != null) {
39+
swRotateToDrivingDirection.setChecked(
40+
UiPrefs.isOverlayRotationToDrivingDirectionEnabled(prefs)
41+
);
42+
swRotateToDrivingDirection.setOnCheckedChangeListener((btn, checked) ->
43+
prefs.edit()
44+
.putBoolean(UiPrefs.KEY_OVERLAY_ROTATE_TO_DRIVING_DIRECTION, checked)
45+
.apply()
46+
);
47+
}
48+
3749
bindMsSlider(
3850
prefs,
3951
seekOverlayHideDelay,

‎app/src/main/java/com/drivehub/kamera/UiPrefs.java‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ final class UiPrefs {
1111
static final String KEY_ACCENT_COLOR = "accentColor";
1212
static final String KEY_ALLOW_BETA_UPDATES = "allowBetaUpdates";
1313
static final String KEY_OVERLAY_ON_SIGNAL = "overlayOnSignal";
14+
static final String KEY_OVERLAY_ROTATE_TO_DRIVING_DIRECTION = "overlayRotateToDrivingDirection";
1415
static final String KEY_OVERLAY_HIDE_DELAY_MS = "overlayHideDelayMs";
1516
static final String KEY_OVERLAY_MIN_SHOW_MS = "overlayMinShowMs";
1617
static final String KEY_DEV_DEFAULT_POLL_MS = "devDefaultPollMs";
@@ -54,6 +55,10 @@ static int getOverlayMinShowMs(SharedPreferences prefs) {
5455
return clampOverlayMinShowMs((int) value);
5556
}
5657

58+
static boolean isOverlayRotationToDrivingDirectionEnabled(SharedPreferences prefs) {
59+
return prefs.getBoolean(KEY_OVERLAY_ROTATE_TO_DRIVING_DIRECTION, false);
60+
}
61+
5762
static int getDevDefaultPollMs(SharedPreferences prefs) {
5863
return clampDevPollingMs(prefs.getInt(KEY_DEV_DEFAULT_POLL_MS, DEFAULT_DEV_DEFAULT_POLLING_MS));
5964
}

‎app/src/main/res/layout/dialog_settings_section_signal_camera.xml‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,25 @@
3232

3333
</LinearLayout>
3434

35+
<LinearLayout
36+
android:layout_width="match_parent"
37+
android:layout_height="60dp"
38+
android:gravity="center_vertical"
39+
android:orientation="horizontal">
40+
41+
<TextView
42+
style="@style/DrivehubSettingsLabel"
43+
android:layout_width="0dp"
44+
android:layout_height="wrap_content"
45+
android:layout_weight="1"
46+
android:text="@string/settings_overlay_rotate_to_driving_direction" />
47+
48+
<Switch
49+
android:id="@+id/switchOverlayRotateToDrivingDirection"
50+
style="@style/DrivehubSettingsSwitch" />
51+
52+
</LinearLayout>
53+
3554
<TextView
3655
style="@style/DrivehubSettingsHeading2"
3756
android:layout_width="match_parent"

‎app/src/main/res/values-de/strings.xml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
<string name="settings_section_display">ANZEIGE</string>
1010
<string name="settings_section_signal_camera">BLINKER-KAMERA</string>
1111
<string name="settings_overlay_on_signal">Kamera beim Blinken anzeigen</string>
12+
<string name="settings_overlay_rotate_to_driving_direction">Spiegelkameras in Fahrtrichtung drehen</string>
1213
<string name="safety_warning_text">Bitte achte auf die Umgebung!</string>
1314
<string name="show_safety_warning">Sicherheitswarnung anzeigen</string>
1415
<string name="settings_section_open_source_credits">OPEN-SOURCE CREDITS</string>

‎app/src/main/res/values/strings.xml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
<string name="settings_section_display">DISPLAY</string>
1010
<string name="settings_section_signal_camera">SIGNAL CAMERA</string>
1111
<string name="settings_overlay_on_signal">Show Signal Camera on turn signal</string>
12+
<string name="settings_overlay_rotate_to_driving_direction">Rotate side cameras to driving direction</string>
1213
<string name="safety_warning_text">Please pay attention to the surrounding environment!</string>
1314
<string name="show_safety_warning">Show safety warning</string>
1415
<string name="settings_section_open_source_credits">OPEN SOURCE CREDITS</string>

0 commit comments

Comments
 (0)