ui: optionally prevent screen shots and insecure displays (#5166)

Introduce new Settings / User interface / Screenshots to optionally prevent screenshots and viewing on non-secure displays.
Toggling this setting requires a GB restart to become fully effective.
This commit is contained in:
Thomas Kuehne
2025-07-29 20:57:27 +02:00
committed by José Rebelo
parent 28e39edea1
commit bba747cb6c
5 changed files with 65 additions and 0 deletions
@@ -21,6 +21,7 @@
package nodomain.freeyourgadget.gadgetbridge;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.Application;
import android.app.NotificationManager;
@@ -41,12 +42,17 @@ import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.os.Build;
import android.os.Build.VERSION;
import android.os.Bundle;
import android.os.StrictMode;
import android.preference.PreferenceManager;
import android.provider.ContactsContract.PhoneLookup;
import android.util.Log;
import android.util.TypedValue;
import android.view.Window;
import android.view.WindowManager;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.core.app.NotificationCompat;
import androidx.core.content.ContextCompat;
@@ -311,6 +317,8 @@ public class GBApplication extends Application {
setupExceptionHandler(prefs.getBoolean("crash_notification", isDebug()));
registerActivityLifecycleCallbacks(new GBActivityLifecycleCallbacks());
Weather.initializeCache(new WeatherCacheManager(getCacheDir(), prefs.getBoolean("cache_weather", true)));
deviceManager = new DeviceManager(this);
@@ -2259,4 +2267,40 @@ public class GBApplication extends Application {
public void setAutoExportScheduledTimestamp(long autoExportScheduledTimestamp) {
this.autoExportScheduledTimestamp = autoExportScheduledTimestamp;
}
private static class GBActivityLifecycleCallbacks implements ActivityLifecycleCallbacks{
@Override
public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) {
boolean preventScreenshots = getPrefs().getBoolean(GBPrefs.BLOCK_SCREENSHOTS, false);
if (preventScreenshots) {
GB.log("set FLAG_SECURE for " + activity.getLocalClassName(), GB.DEBUG, null);
Window window = activity.getWindow();
window.setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);
}
}
@Override
public void onActivityDestroyed(@NonNull Activity activity) {
}
@Override
public void onActivityPaused(@NonNull Activity activity) {
}
@Override
public void onActivityResumed(@NonNull Activity activity) {
}
@Override
public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState) {
}
@Override
public void onActivityStarted(@NonNull Activity activity) {
}
@Override
public void onActivityStopped(@NonNull Activity activity) {
}
}
}
@@ -70,6 +70,7 @@ public class GBPrefs extends Prefs {
public static final String LAST_DEVICE_ADDRESSES = "last_device_addresses";
public static final String RECONNECT_ONLY_TO_CONNECTED = "general_reconnectonlytoconnected";
public static final String BLOCK_SCREENSHOTS = "block_screenshots";
@Deprecated
public GBPrefs(Prefs prefs) {
@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M480,568Q435,568 403.5,536.5Q372,505 372,460Q372,415 403.5,383.5Q435,352 480,352Q525,352 556.5,383.5Q588,415 588,460Q588,505 556.5,536.5Q525,568 480,568ZM480,760Q334,760 214,678.5Q94,597 40,460Q94,323 214,241.5Q334,160 480,160Q621,160 737.5,236Q854,312 912,440L821,440Q769,347 678,293.5Q587,240 480,240Q367,240 272.5,299.5Q178,359 128,460Q178,561 272.5,620.5Q367,680 480,680Q500,680 520,678Q540,676 560,672L560,753Q540,756 520,758Q500,760 480,760ZM480,640Q502,640 522.5,635Q543,630 561,621Q566,571 592.5,531Q619,491 660,467Q660,465 660,463.5Q660,462 660,460Q660,385 607.5,332.5Q555,280 480,280Q405,280 352.5,332.5Q300,385 300,460Q300,535 352.5,587.5Q405,640 480,640ZM475,460Q475,460 475,460Q475,460 475,460Q475,460 475,460Q475,460 475,460Q475,460 475,460Q475,460 475,460L475,460Q475,460 475,460Q475,460 475,460L475,460Q475,460 475,460Q475,460 475,460ZM680,840Q663,840 651.5,828.5Q640,817 640,800L640,680Q640,663 651.5,651.5Q663,640 680,640L680,640L680,600Q680,567 703.5,543.5Q727,520 760,520Q793,520 816.5,543.5Q840,567 840,600L840,640L840,640Q857,640 868.5,651.5Q880,663 880,680L880,800Q880,817 868.5,828.5Q857,840 840,840L680,840ZM720,640L800,640L800,600Q800,583 788.5,571.5Q777,560 760,560Q743,560 731.5,571.5Q720,583 720,600L720,640Z"/>
</vector>
+2
View File
@@ -252,6 +252,8 @@
<string name="map_theme_osmarender">Osmarender</string>
<string name="map_theme_motorider">Motorider</string>
<string name="pref_theme_black_background">Use black background in Dark Theme</string>
<string name="pref_title_block_screenshot">Block screenshots</string>
<string name="pref_summary_block_screenshots">Prevent screenshots and viewing on non-secure displays. Requires a GB restart to become fully effective.</string>
<string name="pref_title_language">Language</string>
<string name="pref_title_minimize_priority">Hide the Gadgetbridge notification</string>
<string name="pref_summary_minimize_priority_off">The icon in the status bar and the notification in the lockscreen are shown</string>
+8
View File
@@ -173,6 +173,14 @@
android:title="@string/pref_theme_black_background"
app:iconSpaceReserved="false" />
<SwitchPreferenceCompat
android:defaultValue="false"
android:icon="@drawable/ic_visibility_lock"
android:key="block_screenshots"
android:layout="@layout/preference_checkbox"
android:summary="@string/pref_summary_block_screenshots"
android:title="@string/pref_title_block_screenshot" />
<PreferenceCategory
android:key="pref_screen_theme"
android:title="@string/pref_header_main_screen"