Skip to content
This repository was archived by the owner on Dec 18, 2022. It is now read-only.

Commit 8b115bb

Browse files
authored
Merge pull request #76 from 05nelsonm/mn/feature/network-receiver-delayed-disable
Add a delay to setting Tor conf DisableNetwork on connectivity change
2 parents 8832d35 + 14764a8 commit 8b115bb

File tree

17 files changed

+321
-196
lines changed

17 files changed

+321
-196
lines changed

sampleapp/src/main/java/io/matthewnelson/sampleapp/App.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ class App: Application() {
159159
application: Application,
160160
serviceNotificationBuilder: ServiceNotification.Builder,
161161
backgroundManagerPolicy: BackgroundManager.Builder.Policy,
162+
disableNetworkDelay: Long,
162163
restartTimeDelay: Long,
163164
stopServiceTimeDelay: Long,
164165
stopServiceOnTaskRemoved: Boolean,
@@ -173,6 +174,7 @@ class App: Application() {
173174
geoipAssetPath = "common/geoip",
174175
geoip6AssetPath = "common/geoip6"
175176
)
177+
.addTimeToDisableNetworkDelay(disableNetworkDelay)
176178
.addTimeToRestartTorDelay(restartTimeDelay)
177179
.addTimeToStopServiceDelay(stopServiceTimeDelay)
178180
.disableStopServiceOnTaskRemoved(stopServiceOnTaskRemoved)
@@ -200,6 +202,7 @@ class App: Application() {
200202
this,
201203
serviceNotificationBuilder,
202204
generateBackgroundManagerPolicy(prefs),
205+
LibraryPrefs.getControllerDisableNetworkDelay(prefs),
203206
LibraryPrefs.getControllerRestartDelaySetting(prefs),
204207
stopTorDelaySettingAtAppStartup.toLong(),
205208
LibraryPrefs.getControllerDisableStopServiceOnTaskRemovedSetting(prefs),
@@ -224,6 +227,7 @@ class App: Application() {
224227
this,
225228
serviceNotificationBuilder,
226229
generateBackgroundManagerPolicy(prefs, BackgroundPolicy.RUN_IN_FOREGROUND, true),
230+
LibraryPrefs.getControllerDisableNetworkDelay(prefs),
227231
LibraryPrefs.getControllerRestartDelaySetting(prefs),
228232
stopTorDelaySettingAtAppStartup.toLong(),
229233
LibraryPrefs.getControllerDisableStopServiceOnTaskRemovedSetting(prefs),

sampleapp/src/main/java/io/matthewnelson/sampleapp/ui/fragments/settings/library/SettingsLibraryFragment.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ class SettingsLibraryFragment : Fragment() {
148148
view.context.applicationContext as Application,
149149
notificationBuilder,
150150
backgroundManagerPolicy,
151+
controllerOptions.getDisableNetworkDelayValue(),
151152
controllerOptions.getRestartDelayValue(),
152153
controllerOptions.getStopDelayTime(),
153154
controllerOptions.disableStopServiceOnTaskRemoved,

sampleapp/src/main/java/io/matthewnelson/sampleapp/ui/fragments/settings/library/components/ControllerOptions.kt

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -87,32 +87,34 @@ class ControllerOptions(view: View, prefs: Prefs) {
8787
const val RELEASE = "Release"
8888
}
8989

90+
private var initialDisableNetworkDelayTime: Long =
91+
LibraryPrefs.getControllerDisableNetworkDelay(prefs)
92+
9093
private var initialRestartDelayTime: Long =
91-
LibraryPrefs.getControllerRestartDelaySetting(
92-
prefs
93-
)
94+
LibraryPrefs.getControllerRestartDelaySetting(prefs)
9495

9596
private var initialStopDelayTime: Long =
96-
LibraryPrefs.getControllerStopDelaySetting(
97-
prefs
98-
)
97+
LibraryPrefs.getControllerStopDelaySetting(prefs)
9998

10099
private var initialDisableStopServiceOnTaskRemoved: Boolean =
101-
LibraryPrefs.getControllerDisableStopServiceOnTaskRemovedSetting(
102-
prefs
103-
)
100+
LibraryPrefs.getControllerDisableStopServiceOnTaskRemovedSetting(prefs)
101+
104102
var disableStopServiceOnTaskRemoved: Boolean = initialDisableStopServiceOnTaskRemoved
105103
private set
106104

107105
private var initialBuildConfigDebug: Boolean =
108-
LibraryPrefs.getControllerBuildConfigDebugSetting(
109-
prefs
110-
)
106+
LibraryPrefs.getControllerBuildConfigDebugSetting(prefs)
107+
111108
var buildConfigDebug: Boolean = initialBuildConfigDebug
112109
private set
113110

114111
fun saveSettings(prefs: Prefs): Boolean {
115112
var somethingChanged = false
113+
if (getDisableNetworkDelayValue() != initialDisableNetworkDelayTime) {
114+
prefs.write(LibraryPrefs.CONTROLLER_DISABLE_NETWORK_DELAY, getDisableNetworkDelayValue())
115+
initialDisableNetworkDelayTime = getDisableNetworkDelayValue()
116+
somethingChanged = true
117+
}
116118
if (getRestartDelayValue() != initialRestartDelayTime) {
117119
prefs.write(LibraryPrefs.CONTROLLER_RESTART_DELAY, getRestartDelayValue())
118120
initialRestartDelayTime = getRestartDelayValue()
@@ -136,6 +138,9 @@ class ControllerOptions(view: View, prefs: Prefs) {
136138
return somethingChanged
137139
}
138140

141+
fun getDisableNetworkDelayValue(): Long =
142+
getEditTextValueLong(editTextDisableNetworkDelay)
143+
139144
fun getRestartDelayValue(): Long =
140145
getEditTextValueLong(editTextRestartDelay)
141146

@@ -150,6 +155,7 @@ class ControllerOptions(view: View, prefs: Prefs) {
150155
}
151156
}
152157

158+
private lateinit var editTextDisableNetworkDelay: EditText
153159
private lateinit var editTextRestartDelay: EditText
154160
private lateinit var editTextStopDelay: EditText
155161
private lateinit var spinnerDisableStopOnTaskRemoved: Spinner
@@ -165,18 +171,25 @@ class ControllerOptions(view: View, prefs: Prefs) {
165171
}
166172

167173
private fun findViews(view: View) {
174+
editTextDisableNetworkDelay = view.findViewById(R.id.settings_library_edit_text_controller_disable_network_delay)
168175
editTextRestartDelay = view.findViewById(R.id.settings_library_edit_text_controller_restart_delay)
169176
editTextStopDelay = view.findViewById(R.id.settings_library_edit_text_controller_stop_delay)
170177
spinnerDisableStopOnTaskRemoved = view.findViewById(R.id.settings_library_spinner_controller_stop_on_task_removed)
171178
spinnerBuildConfig = view.findViewById(R.id.settings_library_spinner_controller_build_config)
172179
}
173180

174181
private fun initEditTextViews() {
182+
editTextDisableNetworkDelay.filters = arrayOf(InputFilter.LengthFilter(4))
183+
if (initialDisableNetworkDelayTime > 0L)
184+
editTextDisableNetworkDelay.setText(initialDisableNetworkDelayTime.toString())
185+
175186
editTextRestartDelay.filters = arrayOf(InputFilter.LengthFilter(4))
176-
editTextRestartDelay.setText(initialRestartDelayTime.toString())
187+
if (initialRestartDelayTime > 0L)
188+
editTextRestartDelay.setText(initialRestartDelayTime.toString())
177189

178190
editTextStopDelay.filters = arrayOf(InputFilter.LengthFilter(4))
179-
editTextStopDelay.setText(initialStopDelayTime.toString())
191+
if (initialStopDelayTime > 0L)
192+
editTextStopDelay.setText(initialStopDelayTime.toString())
180193
}
181194

182195
private fun initSpinnerControllerDisableStopOnTaskRemoved(context: Context) {

sampleapp/src/main/java/io/matthewnelson/sampleapp/ui/fragments/settings/library/components/LibraryPrefs.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ object LibraryPrefs {
8888

8989
// Controller Keys
9090
const val CONTROLLER_BUILD_CONFIG_DEBUG = "CONTROLLER_BUILD_CONFIG_DEBUG"
91+
const val CONTROLLER_DISABLE_NETWORK_DELAY = "CONTROLLER_DISABLE_NETWORK_DELAY"
9192
const val CONTROLLER_RESTART_DELAY = "CONTROLLER_RESTART_DELAY"
9293
const val CONTROLLER_STOP_DELAY = "CONTROLLER_STOP_DELAY"
9394
const val CONTROLLER_DISABLE_STOP_SERVICE_TASK_REMOVED = "CONTROLLER_DISABLE_STOP_SERVICE_TASK_REMOVED"
@@ -119,6 +120,9 @@ object LibraryPrefs {
119120
prefs.read(BACKGROUND_MANAGER_KILL_APP, true)
120121

121122
// Controller Settings
123+
fun getControllerDisableNetworkDelay(prefs: Prefs): Long =
124+
prefs.read(CONTROLLER_DISABLE_NETWORK_DELAY, 0L)
125+
122126
fun getControllerRestartDelaySetting(prefs: Prefs): Long =
123127
prefs.read(CONTROLLER_RESTART_DELAY, 100L)
124128

sampleapp/src/main/res/layout/fragment_settings_library.xml

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,26 @@
329329
android:orientation="vertical"
330330
app:layout_constraintGuide_percent=".40" />
331331

332+
<TextView
333+
android:id="@+id/settings_library_text_view_controller_disable_network_delay"
334+
style="@style/SpinnerTextView"
335+
android:text="@string/settings_library_text_view_controller_disable_network_delay"
336+
app:layout_constraintBottom_toBottomOf="@+id/settings_library_edit_text_controller_disable_network_delay"
337+
app:layout_constraintEnd_toEndOf="@+id/settings_library_controller_guide_left"
338+
app:layout_constraintStart_toStartOf="parent"
339+
app:layout_constraintTop_toTopOf="@+id/settings_library_edit_text_controller_disable_network_delay" />
340+
341+
<EditText
342+
android:id="@+id/settings_library_edit_text_controller_disable_network_delay"
343+
android:layout_width="0dp"
344+
android:layout_height="wrap_content"
345+
android:gravity="center_horizontal"
346+
android:hint="@string/settings_library_edit_text_controller_disable_network_delay"
347+
android:inputType="number"
348+
app:layout_constraintEnd_toEndOf="parent"
349+
app:layout_constraintStart_toEndOf="@+id/settings_library_controller_guide_left"
350+
app:layout_constraintTop_toTopOf="parent" />
351+
332352
<TextView
333353
android:id="@+id/settings_library_text_view_controller_restart_delay"
334354
style="@style/SpinnerTextView"
@@ -347,7 +367,7 @@
347367
android:inputType="number"
348368
app:layout_constraintEnd_toEndOf="parent"
349369
app:layout_constraintStart_toEndOf="@+id/settings_library_controller_guide_left"
350-
app:layout_constraintTop_toTopOf="parent" />
370+
app:layout_constraintTop_toBottomOf="@+id/settings_library_edit_text_controller_disable_network_delay" />
351371

352372
<TextView
353373
android:id="@+id/settings_library_text_view_controller_stop_delay"

sampleapp/src/main/res/values/strings.xml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,11 @@
6565
implementing the Library into your own application</string>
6666

6767
<string name="settings_library_button_save">Save Settings</string>
68-
<string name="settings_library_text_view_controller_restart_delay">Restart Delay (ms):</string>
68+
<string name="settings_library_text_view_controller_disable_network_delay">Disable Net Delay:</string>
69+
<string name="settings_library_edit_text_controller_disable_network_delay">6_000ms + your value</string>
70+
<string name="settings_library_text_view_controller_restart_delay">Restart Delay:</string>
6971
<string name="settings_library_edit_text_controller_restart_delay">500ms + your value</string>
70-
<string name="settings_library_text_view_controller_stop_delay">Stop Delay (ms):</string>
72+
<string name="settings_library_text_view_controller_stop_delay">Stop Delay:</string>
7173
<string name="settings_library_edit_text_controller_stop_delay">100ms + your value</string>
7274
<string name="settings_library_text_view_controller_stop_on_task_removed">On Task Removed:</string>
7375
<string name="settings_library_text_view_controller_build_config">Build Config:</string>

topl-core/src/main/java/io/matthewnelson/topl_core/OnionProxyManager.kt

Lines changed: 24 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -90,11 +90,9 @@
9090
package io.matthewnelson.topl_core
9191

9292
import android.content.Context
93-
import android.content.IntentFilter
9493
import android.net.ConnectivityManager
9594
import io.matthewnelson.topl_core_base.EventBroadcaster
9695
import io.matthewnelson.topl_core.listener.BaseEventListener
97-
import io.matthewnelson.topl_core.receiver.NetworkStateReceiver
9896
import io.matthewnelson.topl_core.settings.TorSettingsBuilder
9997
import io.matthewnelson.topl_core.broadcaster.BroadcastLogger
10098
import io.matthewnelson.topl_core.broadcaster.BroadcastLoggerHelper
@@ -220,8 +218,6 @@ class OnionProxyManager(
220218
broadcastLogger.warn("TorControlConnection is not responding properly to $methodCall")
221219
}
222220

223-
@Volatile
224-
private var networkStateReceiver: NetworkStateReceiver? = null
225221
@Volatile
226222
private var controlSocket: Socket? = null
227223
// If controlConnection is not null then this means that a connection exists and the Tor OP
@@ -384,21 +380,6 @@ class OnionProxyManager(
384380
}
385381

386382
torStateMachine.setTorState(TorState.OFF)
387-
388-
if (networkStateReceiver == null) return
389-
390-
try {
391-
appContext.unregisterReceiver(networkStateReceiver)
392-
} catch (e: IllegalArgumentException) {
393-
// There is a race condition where if someone calls stop before
394-
// installAndStartTorOp is done then we could get an exception because
395-
// the network state receiver might not be properly registered.
396-
broadcastLogger.exception(
397-
IllegalArgumentException(
398-
"Someone tried calling stop before registering of NetworkStateReceiver", e
399-
)
400-
)
401-
}
402383
}
403384
}
404385

@@ -416,6 +397,13 @@ class OnionProxyManager(
416397
false
417398
}
418399

400+
@Suppress("DEPRECATION")
401+
fun hasNetworkConnectivity(): Boolean {
402+
val connectivityManager = appContext
403+
.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager?
404+
return connectivityManager?.activeNetworkInfo?.isConnected ?: false
405+
}
406+
419407
private val disableNetworkLock = Object()
420408
/**
421409
* Tells the Tor OP if it should accept network connections.
@@ -424,11 +412,12 @@ class OnionProxyManager(
424412
* such that [torStateMachine] will reflect the proper
425413
* [io.matthewnelson.topl_core_base.BaseConsts.TorNetworkState].
426414
*
427-
* @param [disable] If true then the Tor OP will **not** accept SOCKS connections, otherwise yes.
415+
* @param [disable] Sets Tor config DisableNetwork (1 if `true`, 0 if `false`)
428416
* @throws [IOException] if having issues with TorControlConnection#setConf
429-
* @throws [KotlinNullPointerException] if [controlConnection] is null even after checking.
417+
* @throws [NullPointerException] if [controlConnection] is null even after checking.
430418
*/
431-
@Throws(IOException::class, KotlinNullPointerException::class)
419+
@Synchronized
420+
@Throws(IOException::class, NullPointerException::class)
432421
fun disableNetwork(disable: Boolean) {
433422
synchronized(disableNetworkLock) {
434423
if (!hasControlConnection) return
@@ -518,6 +507,11 @@ class OnionProxyManager(
518507
/**
519508
* Starts tor control service if it isn't already running.
520509
*
510+
* If the device does not have connectivity, [disableNetwork] will not be called to set
511+
* Tor's config for DisableNetwork to false (0). Handling connectivity changes should be done
512+
* via your own [android.content.BroadcastReceiver] and by calling [disableNetwork] when
513+
* appropriate.
514+
*
521515
* @throws [IOException] File errors
522516
* @throws [SecurityException] Unauthorized access to file/directory.
523517
* @throws [IllegalArgumentException] if [onionProxyContext] methods are passed incorrect
@@ -589,7 +583,13 @@ class OnionProxyManager(
589583
controlConnection.setEvents(listOf(*eventListener.CONTROL_COMMAND_EVENTS))
590584
}
591585

592-
disableNetwork(false)
586+
if (hasNetworkConnectivity())
587+
disableNetwork(false)
588+
else
589+
broadcastLogger.warn(
590+
"No Network Connectivity. Foregoing enabling of Tor Network."
591+
)
592+
593593
} catch (e: Exception) {
594594
torProcess?.destroy()
595595
this.controlConnection = null
@@ -599,12 +599,6 @@ class OnionProxyManager(
599599
}
600600

601601
torStateMachine.setTorState(TorState.ON)
602-
603-
networkStateReceiver = NetworkStateReceiver(this)
604-
605-
@Suppress("DEPRECATION")
606-
val filter = IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)
607-
appContext.registerReceiver(networkStateReceiver, filter)
608602
broadcastLogger.notice("Completed starting of Tor")
609603
}
610604

@@ -894,7 +888,7 @@ class OnionProxyManager(
894888
@Synchronized
895889
suspend fun signalNewNym() {
896890
if (!hasControlConnection || !isBootstrapped) return
897-
if (networkStateReceiver?.networkConnectivity != true) {
891+
if (!hasNetworkConnectivity()) {
898892
broadcastLogger.notice("NEWNYM: $NEWNYM_NO_NETWORK")
899893
return
900894
}

0 commit comments

Comments
 (0)