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 38172e36ff

View File

@ -8,6 +8,7 @@ import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.SyncStatusObserver;
import android.content.res.Resources;
import android.hardware.display.DisplayManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiInfo;
@ -17,6 +18,7 @@ import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.os.PowerManager;
import android.view.Display;
import androidx.annotation.Nullable;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import android.os.SystemClock;
@ -156,6 +158,12 @@ public class RunConditionMonitor {
new PowerSaveModeChangedReceiver(),
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.
mSyncStatusObserverHandle = ContentResolver.addStatusChangeListener(
ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS, mSyncStatusObserver);
@ -263,6 +271,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 {
@Override
public void onReceive(Context context, Intent intent) {
@ -556,6 +576,15 @@ public class RunConditionMonitor {
boolean prefRespectMasterSync = mPreferences.getBoolean(Constants.PREF_RESPECT_MASTER_SYNC, false);
boolean prefRunInFlightMode = mPreferences.getBoolean(Constants.PREF_RUN_IN_FLIGHT_MODE, 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
switch (prefBtnStateForceStartStop) {
@ -573,19 +602,27 @@ public class RunConditionMonitor {
// 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)
mTimeConditionMatch = true;
if (prefRunOnTimeSchedule && !mTimeConditionMatch) {
// Currently, we aren't within a "SyncthingNative should run" time frame.
LogV("decideShouldRun: PREF_RUN_ON_TIME_SCHEDULE && !mTimeConditionMatch");
int minutes = (int) (SystemClock.elapsedRealtime() - mPreferences.getLong(Constants.PREF_LAST_RUN_TIME,0))/(60*1000);
String minutesText;
if (minutes == 0)
minutesText = res.getString(R.string.reason_not_within_time_frame_0_min);
else
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);
return false;
if (prefRunOnTimeSchedule && !mTimeConditionMatch && (!prefRunOnTimeScheduleOnlyWhenScreenOff || !isScreenOn)) {
// Currently, we aren't within a "SyncthingNative should run" time frame.
LogV("decideShouldRun: PREF_RUN_ON_TIME_SCHEDULE && !mTimeConditionMatch");
int minutes = (int) (SystemClock.elapsedRealtime() - mPreferences.getLong(Constants.PREF_LAST_RUN_TIME,0))/(60*1000);
String minutesText;
if (minutes == 0)
minutesText = res.getString(R.string.reason_not_within_time_frame_0_min);
else
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);
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
SyncConditionResult scr = checkConditionSyncOnPowerSource(Constants.PREF_POWER_SOURCE);
if (!scr.conditionMet) {
@ -743,6 +780,15 @@ public class RunConditionMonitor {
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() {
ConnectivityManager cm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo ni = cm.getActiveNetworkInfo();