Added code to ignore schedule when the screen is on
Some checks are pending
Build App / Debug Build (push) Waiting to run
CodeQL Advanced / Analyze (${{ matrix.language }}) (none, actions) (push) Waiting to run
CodeQL Advanced / Analyze (${{ matrix.language }}) (none, python) (push) Waiting to run

This commit is contained in:
Youen 2025-08-14 20:02:15 +00:00
parent 2b4dcdc44f
commit 031d62e1fe

View File

@ -8,6 +8,7 @@ import android.content.IntentFilter;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.SyncStatusObserver; import android.content.SyncStatusObserver;
import android.content.res.Resources; import android.content.res.Resources;
import android.hardware.display.DisplayManager;
import android.net.ConnectivityManager; import android.net.ConnectivityManager;
import android.net.NetworkInfo; import android.net.NetworkInfo;
import android.net.wifi.WifiInfo; import android.net.wifi.WifiInfo;
@ -17,6 +18,7 @@ import android.os.Build;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.os.PowerManager; import android.os.PowerManager;
import android.view.Display;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.localbroadcastmanager.content.LocalBroadcastManager; import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import android.os.SystemClock; import android.os.SystemClock;
@ -155,6 +157,12 @@ public class RunConditionMonitor {
ReceiverManager.registerReceiver(mContext, ReceiverManager.registerReceiver(mContext,
new PowerSaveModeChangedReceiver(), new PowerSaveModeChangedReceiver(),
new IntentFilter(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED)); new IntentFilter(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED));
// ScreenStateReceiver
IntentFilter screenStateFilter = new IntentFilter();
screenStateFilter.addAction(Intent.ACTION_SCREEN_ON);
screenStateFilter.addAction(Intent.ACTION_SCREEN_OFF);
ReceiverManager.registerReceiver(mContext, new ScreenStateReceiver(), screenStateFilter);
// SyncStatusObserver to monitor android's "AutoSync" quick toggle. // SyncStatusObserver to monitor android's "AutoSync" quick toggle.
mSyncStatusObserverHandle = ContentResolver.addStatusChangeListener( mSyncStatusObserverHandle = ContentResolver.addStatusChangeListener(
@ -262,6 +270,18 @@ public class RunConditionMonitor {
} }
} }
} }
private class ScreenStateReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_SCREEN_ON.equals(intent.getAction())
|| Intent.ACTION_SCREEN_OFF.equals(intent.getAction())) {
LogV("ScreenStateReceiver: onReceive");
SystemClock.sleep(5000);
updateShouldRunDecision();
}
}
}
private class SyncTriggerReceiver extends BroadcastReceiver { private class SyncTriggerReceiver extends BroadcastReceiver {
@Override @Override
@ -556,6 +576,15 @@ public class RunConditionMonitor {
boolean prefRespectMasterSync = mPreferences.getBoolean(Constants.PREF_RESPECT_MASTER_SYNC, false); boolean prefRespectMasterSync = mPreferences.getBoolean(Constants.PREF_RESPECT_MASTER_SYNC, false);
boolean prefRunInFlightMode = mPreferences.getBoolean(Constants.PREF_RUN_IN_FLIGHT_MODE, false); boolean prefRunInFlightMode = mPreferences.getBoolean(Constants.PREF_RUN_IN_FLIGHT_MODE, false);
boolean prefRunOnTimeSchedule = mPreferences.getBoolean(Constants.PREF_RUN_ON_TIME_SCHEDULE, false); boolean prefRunOnTimeSchedule = mPreferences.getBoolean(Constants.PREF_RUN_ON_TIME_SCHEDULE, false);
boolean prefRunOnTimeScheduleOnlyWhenScreenOff = true; // TODO: add a checkbox in the app preferences
boolean isScreenOn = isDeviceInteractive();
/*DisplayManager dm = (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE);
for (Display display : dm.getDisplays()) {
if (display.getState() != Display.STATE_OFF) {
isScreenOn = true;
}
}*/
// PREF_BTNSTATE_FORCE_START_STOP // PREF_BTNSTATE_FORCE_START_STOP
switch (prefBtnStateForceStartStop) { switch (prefBtnStateForceStartStop) {
@ -573,18 +602,26 @@ public class RunConditionMonitor {
// set mTimeConditionMatch to true if the last run was more than WAIT_FOR_NEXT_SYNC_DELAY_SECS ago // set mTimeConditionMatch to true if the last run was more than WAIT_FOR_NEXT_SYNC_DELAY_SECS ago
if (SystemClock.elapsedRealtime() - mPreferences.getLong(Constants.PREF_LAST_RUN_TIME,0) > Integer.parseInt(mPreferences.getString(Constants.PREF_SLEEP_INTERVAL_MINUTES,"60")) * 60 * 1000) if (SystemClock.elapsedRealtime() - mPreferences.getLong(Constants.PREF_LAST_RUN_TIME,0) > Integer.parseInt(mPreferences.getString(Constants.PREF_SLEEP_INTERVAL_MINUTES,"60")) * 60 * 1000)
mTimeConditionMatch = true; mTimeConditionMatch = true;
if (prefRunOnTimeSchedule && !mTimeConditionMatch) { if (prefRunOnTimeSchedule && !mTimeConditionMatch && (!prefRunOnTimeScheduleOnlyWhenScreenOff || !isScreenOn)) {
// Currently, we aren't within a "SyncthingNative should run" time frame. // Currently, we aren't within a "SyncthingNative should run" time frame.
LogV("decideShouldRun: PREF_RUN_ON_TIME_SCHEDULE && !mTimeConditionMatch"); LogV("decideShouldRun: PREF_RUN_ON_TIME_SCHEDULE && !mTimeConditionMatch");
int minutes = (int) (SystemClock.elapsedRealtime() - mPreferences.getLong(Constants.PREF_LAST_RUN_TIME,0))/(60*1000); int minutes = (int) (SystemClock.elapsedRealtime() - mPreferences.getLong(Constants.PREF_LAST_RUN_TIME,0))/(60*1000);
String minutesText; String minutesText;
if (minutes == 0) if (minutes == 0)
minutesText = res.getString(R.string.reason_not_within_time_frame_0_min); minutesText = res.getString(R.string.reason_not_within_time_frame_0_min);
else else
minutesText = String.format(res.getQuantityString(R.plurals.reason_not_within_time_frame_minutes,minutes),minutes); minutesText = String.format(res.getQuantityString(R.plurals.reason_not_within_time_frame_minutes,minutes),minutes);
mRunDecisionExplanation = String.format(res.getString(R.string.reason_not_within_time_frame_2),minutesText); mRunDecisionExplanation = String.format(res.getString(R.string.reason_not_within_time_frame_2),minutesText);
return false; if (prefRunOnTimeScheduleOnlyWhenScreenOff) {
LogV("decideShouldRun: screen is off");
mRunDecisionExplanation += " and the screen is off";
}
return false;
} }
if (prefRunOnTimeSchedule && prefRunOnTimeScheduleOnlyWhenScreenOff || isScreenOn) {
mRunDecisionExplanation += "The schedule is ignored because the screen is on\n";
}
// PREF_POWER_SOURCE // PREF_POWER_SOURCE
SyncConditionResult scr = checkConditionSyncOnPowerSource(Constants.PREF_POWER_SOURCE); SyncConditionResult scr = checkConditionSyncOnPowerSource(Constants.PREF_POWER_SOURCE);
@ -742,6 +779,15 @@ public class RunConditionMonitor {
} }
return powerManager.isPowerSaveMode(); return powerManager.isPowerSaveMode();
} }
private boolean isDeviceInteractive() {
PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
if (powerManager == null) {
Log.e(TAG, "getSystemService(POWER_SERVICE) unexpectedly returned NULL.");
return false;
}
return powerManager.isInteractive();
}
private boolean isFlightMode() { private boolean isFlightMode() {
ConnectivityManager cm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE); ConnectivityManager cm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);