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

Commit 51769d8

Browse files
authored
Merge pull request #66 from 05nelsonm/mn/feature/sample-app-upgrades
Sample App Upgrades
2 parents 1706c3b + 67559ee commit 51769d8

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+3552
-350
lines changed

gradle/dependencies.gradle

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,13 @@ ext.versions = [
66
'coroutines': '1.3.8',
77
'lifecycle': '2.2.0',
88
'kotlin': '1.3.72',
9+
'navigation': '2.3.0',
910
]
1011

1112
ext.deps = [
1213
androidGradlePlugin: "com.android.tools.build:gradle:4.0.1",
1314
androidx: [
14-
appCompat: "androidx.appcompat:appcompat:1.1.0",
15+
appCompat: "androidx.appcompat:appcompat:1.2.0",
1516
constraintLayout: "androidx.constraintlayout:constraintlayout:1.1.3",
1617
core: "androidx.core:core-ktx:1.3.1",
1718
lifecycle: [
@@ -22,6 +23,12 @@ ext.deps = [
2223
runtime: "androidx.lifecycle:lifecycle-runtime-ktx:${versions.lifecycle}",
2324
service: "androidx.lifecycle:lifecycle-service:${versions.lifecycle}",
2425
],
26+
navigation: [
27+
fragment: "androidx.navigation:navigation-fragment:${versions.navigation}",
28+
fragmentKtx: "androidx.navigation:navigation-fragment-ktx:${versions.navigation}",
29+
ui: "androidx.navigation:navigation-ui:${versions.navigation}",
30+
uiKtx: "androidx.navigation:navigation-ui-ktx:${versions.navigation}",
31+
],
2532
recyclerView: "androidx.recyclerview:recyclerview:1.1.0",
2633
test: [
2734
core: "androidx.test:core:1.2.0",

sampleapp/build.gradle

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,12 +97,18 @@ dependencies {
9797
implementation deps.androidx.lifecycle.commonJava8
9898
implementation deps.androidx.lifecycle.liveData
9999
implementation deps.androidx.lifecycle.reactiveStreams
100+
implementation deps.androidx.navigation.fragment
101+
implementation deps.androidx.navigation.fragmentKtx
102+
implementation deps.androidx.navigation.ui
103+
implementation deps.androidx.navigation.uiKtx
100104
implementation deps.androidx.recyclerView
101105
implementation deps.kotlin.coroutinesCore
102106
implementation deps.kotlin.coroutinesAndroid
103107
implementation deps.kotlin.stdlib
104108

109+
implementation 'io.matthewnelson.encrypted-storage:encrypted-storage:2.0.0'
105110
implementation 'io.matthewnelson.topl-android:tor-binary:0.4.3.5a'
111+
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
106112

107113
testImplementation deps.junit
108114

sampleapp/src/main/AndroidManifest.xml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
3+
xmlns:tools="http://schemas.android.com/tools"
34
package="io.matthewnelson.sampleapp">
45

6+
<!-- encrypted_storage dependency requires minSdk 23, but only if using the
7+
encryption (which we're not) -->
8+
<uses-sdk tools:overrideLibrary="io.matthewnelson.encrypted_storage, androidx.security" />
9+
510
<application
611
android:name=".App"
712
android:allowBackup="true"
@@ -10,7 +15,8 @@
1015
android:roundIcon="@mipmap/ic_launcher_round"
1116
android:supportsRtl="true"
1217
android:theme="@style/AppTheme">
13-
<activity android:name=".MainActivity">
18+
<activity android:name=".ui.MainActivity"
19+
android:screenOrientation="portrait" >
1420
<intent-filter>
1521
<action android:name="android.intent.action.MAIN" />
1622

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

Lines changed: 127 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -67,128 +67,151 @@
6767
package io.matthewnelson.sampleapp
6868

6969
import android.app.Application
70-
import android.content.Context
7170
import android.os.Process
72-
import androidx.core.app.NotificationCompat
73-
import io.matthewnelson.topl_core_base.TorConfigFiles
71+
import android.widget.Toast
72+
import io.matthewnelson.encrypted_storage.Prefs
73+
import io.matthewnelson.sampleapp.topl_android.MyEventBroadcaster
74+
import io.matthewnelson.sampleapp.topl_android.MyTorSettings
75+
import io.matthewnelson.sampleapp.ui.MainActivity
76+
import io.matthewnelson.sampleapp.ui.fragments.settings.library.LibraryPrefs
7477
import io.matthewnelson.topl_service.TorServiceController
7578
import io.matthewnelson.topl_service.notification.ServiceNotification
7679
import io.matthewnelson.topl_service.lifecycle.BackgroundManager
77-
import java.io.File
7880

7981
/**
8082
* @suppress
83+
*
84+
* See [io.matthewnelson.sampleapp.topl_android.CodeSamples] for code samples
8185
* */
8286
class App: Application() {
8387

84-
override fun onCreate() {
85-
super.onCreate()
86-
setupTorServices(this, TorConfigFiles.createConfig(this))
87-
TorServiceController.appEventBroadcaster?.let {
88-
(it as MyEventBroadcaster).broadcastLogMessage(
89-
"SampleApp|Application|Process ID: ${Process.myPid()}"
88+
companion object {
89+
const val PREFS_NAME = "TOPL-Android_SampleApp"
90+
lateinit var stopTorDelaySettingAtAppStartup: String
91+
private set
92+
93+
/**
94+
* See [io.matthewnelson.sampleapp.topl_android.CodeSamples.generateTorServiceNotificationBuilder]
95+
* for a cleaner sample
96+
* */
97+
fun generateTorServiceNotificationBuilder(
98+
visibility: Int,
99+
iconColorRes: Int,
100+
enableRestart: Boolean,
101+
enableStop: Boolean,
102+
show: Boolean
103+
): ServiceNotification.Builder {
104+
return ServiceNotification.Builder(
105+
channelName = "TOPL-Android Demo",
106+
channelDescription = "TorOnionProxyLibrary-Android Demo",
107+
channelID = "TOPL-Android Demo",
108+
notificationID = 615
90109
)
110+
.setActivityToBeOpenedOnTap(
111+
clazz = MainActivity::class.java,
112+
intentExtrasKey = null,
113+
intentExtras = null,
114+
intentRequestCode = null
115+
)
116+
117+
.setVisibility(visibility)
118+
.setCustomColor(iconColorRes)
119+
.enableTorRestartButton(enableRestart)
120+
.enableTorStopButton(enableStop)
121+
.showNotification(show)
91122
}
92-
TorServiceController.startTor()
93-
}
94-
95-
private fun generateTorServiceNotificationBuilder(): ServiceNotification.Builder {
96-
// private fun generateTorServiceNotificationBuilder(): ServiceNotification.Builder {
97-
return ServiceNotification.Builder(
98-
channelName = "TorService Channel",
99-
channelDescription = "Tor Channel",
100-
channelID = "My Sample Application",
101-
notificationID = 615
102-
)
103-
.setActivityToBeOpenedOnTap(
104-
clazz = MainActivity::class.java,
105-
intentExtrasKey = null,
106-
intentExtras = null,
107-
intentRequestCode = null
108-
)
109-
.setImageTorNetworkingEnabled(drawableRes = R.drawable.tor_stat_network_enabled)
110-
.setImageTorNetworkingDisabled(drawableRes = R.drawable.tor_stat_network_disabled)
111-
.setImageTorDataTransfer(drawableRes = R.drawable.tor_stat_network_dataxfer)
112-
.setImageTorErrors(drawableRes = R.drawable.tor_stat_notifyerr)
113-
.setVisibility(visibility = NotificationCompat.VISIBILITY_PRIVATE)
114-
.setCustomColor(colorRes = R.color.primaryColor)
115-
.enableTorRestartButton(enable = true)
116-
.enableTorStopButton(enable = true)
117-
.showNotification(show = true)
118-
// }
119-
}
120123

121-
private fun generateBackgroundManagerPolicy(): BackgroundManager.Builder.Policy {
122-
// private fun generateBackgroundManagerPolicy(): BackgroundManager.Builder.Policy {
123-
return BackgroundManager.Builder()
124+
/**
125+
* See [io.matthewnelson.sampleapp.topl_android.CodeSamples.generateBackgroundManagerPolicy]
126+
* for a cleaner sample
127+
* */
128+
fun generateBackgroundManagerPolicy(
129+
prefs: Prefs,
130+
policy: String? = null,
131+
killApp: Boolean? = null,
132+
executionDelay: Int? = null
133+
): BackgroundManager.Builder.Policy {
134+
val builder = BackgroundManager.Builder()
135+
return when (policy ?: LibraryPrefs.getBackgroundManagerPolicySetting(prefs)) {
136+
LibraryPrefs.BACKGROUND_MANAGER_POLICY_FOREGROUND -> {
137+
builder.runServiceInForeground(
138+
killApp ?: LibraryPrefs.getBackgroundManagerKillAppSetting(prefs)
139+
)
140+
}
141+
LibraryPrefs.BACKGROUND_MANAGER_POLICY_RESPECT -> {
142+
builder.respectResourcesWhileInBackground(
143+
executionDelay ?: LibraryPrefs.getBackgroundManagerExecuteDelaySetting(prefs)
144+
)
145+
}
146+
else -> {
147+
builder.respectResourcesWhileInBackground(20)
148+
}
149+
}
150+
}
124151

125-
// All available options present. Only 1 is able to be chosen.
126-
.respectResourcesWhileInBackground(secondsFrom5To45 = 20)
127-
//.runServiceInForeground(killAppIfTaskIsRemoved = true)
128-
// }
152+
/**
153+
* See [io.matthewnelson.sampleapp.topl_android.CodeSamples.setupTorServices]
154+
* for a cleaner sample
155+
* */
156+
fun setupTorServices(
157+
application: Application,
158+
serviceNotificationBuilder: ServiceNotification.Builder,
159+
backgroundManagerPolicy: BackgroundManager.Builder.Policy,
160+
restartTimeDelay: Long,
161+
stopServiceTimeDelay: Long,
162+
stopServiceOnTaskRemoved: Boolean,
163+
buildConfigDebug: Boolean
164+
) {
165+
TorServiceController.Builder(
166+
application = application,
167+
torServiceNotificationBuilder = serviceNotificationBuilder,
168+
backgroundManagerPolicy = backgroundManagerPolicy,
169+
buildConfigVersionCode = BuildConfig.VERSION_CODE,
170+
torSettings = MyTorSettings(),
171+
geoipAssetPath = "common/geoip",
172+
geoip6AssetPath = "common/geoip6"
173+
)
174+
.addTimeToRestartTorDelay(restartTimeDelay)
175+
.addTimeToStopServiceDelay(stopServiceTimeDelay)
176+
.disableStopServiceOnTaskRemoved(stopServiceOnTaskRemoved)
177+
.setBuildConfigDebug(buildConfigDebug)
178+
.setEventBroadcaster(eventBroadcaster = MyEventBroadcaster())
179+
.build()
180+
}
129181
}
130182

131-
private fun setupTorServices(application: Application, torConfigFiles: TorConfigFiles) {
132-
// private fun setupTorServices(application: Application, torConfigFiles: TorConfigFiles ) {
133-
TorServiceController.Builder(
134-
application = application,
135-
torServiceNotificationBuilder = generateTorServiceNotificationBuilder(),
136-
backgroundManagerPolicy = generateBackgroundManagerPolicy(),
137-
buildConfigVersionCode = BuildConfig.VERSION_CODE,
138-
139-
// Can instantiate directly here then access it from
140-
// TorServiceController.Companion.getTorSettings() and cast what's returned
141-
// as MyTorSettings
142-
torSettings = MyTorSettings(),
143-
144-
// These should live somewhere in your module's assets directory,
145-
// ex: my-project/my-application-module/src/main/assets/common/geoip
146-
// ex: my-project/my-application-module/src/main/assets/common/geoip6
147-
geoipAssetPath = "common/geoip",
148-
geoip6AssetPath = "common/geoip6"
183+
override fun onCreate() {
184+
super.onCreate()
185+
val prefs = Prefs.createUnencrypted(PREFS_NAME, this)
186+
187+
val serviceNotificationBuilder = generateTorServiceNotificationBuilder(
188+
LibraryPrefs.getNotificationVisibilitySetting(prefs),
189+
LibraryPrefs.getNotificationColorSetting(prefs),
190+
LibraryPrefs.getNotificationRestartEnableSetting(prefs),
191+
LibraryPrefs.getNotificationStopEnableSetting(prefs),
192+
LibraryPrefs.getNotificationShowSetting(prefs)
149193
)
150-
.addTimeToRestartTorDelay(milliseconds = 100L)
151-
.addTimeToStopServiceDelay(milliseconds = 100L)
152-
.disableStopServiceOnTaskRemoved(disable = false)
153-
.setBuildConfigDebug(buildConfigDebug = BuildConfig.DEBUG)
154-
155-
// Can instantiate directly here then access it from
156-
// TorServiceController.Companion?.appEventBroadcaster and cast what's returned
157-
// as MyEventBroadcaster
158-
.setEventBroadcaster(eventBroadcaster = MyEventBroadcaster())
159-
160-
// Only needed if you wish to customize the directories/files used by Tor if
161-
// the defaults aren't to your liking.
162-
.useCustomTorConfigFiles(torConfigFiles = torConfigFiles)
163-
164-
.build()
165-
// }
166-
}
167-
168-
fun customTorConfigFilesSetup(context: Context): TorConfigFiles {
169-
// fun customTorConfigFilesSetup(context: Context): TorConfigFiles {
170-
171-
// This is modifying the directory hierarchy from TorService's
172-
// default setup. For example, if you are using binaries for Tor that
173-
// are named differently that that expressed in TorConfigFiles.createConfig()
174194

175-
// Post Android API 28 requires that executable files be contained in your
176-
// application's data/app directory, as they can no longer execute from data/data.
177-
val installDir = File(context.applicationInfo.nativeLibraryDir)
178-
179-
// Will create a directory within your application's data/data dir
180-
val configDir = context.getDir("torservice", Context.MODE_PRIVATE)
181-
182-
val builder = TorConfigFiles.Builder(installDir, configDir)
183-
184-
// Customize the tor executable file name. Requires that the executable file
185-
// be in your module's src/main/jniLibs directory. If you are getting your
186-
// executable files via a dependency be sure to consult that Library's documentation.
187-
builder.torExecutable(File(installDir, "libtor.so"))
188-
189-
// customize further via the builder methods...
195+
stopTorDelaySettingAtAppStartup = LibraryPrefs.getControllerStopDelaySetting(prefs).toString()
196+
197+
try {
198+
setupTorServices(
199+
this,
200+
serviceNotificationBuilder,
201+
generateBackgroundManagerPolicy(prefs),
202+
LibraryPrefs.getControllerRestartDelaySetting(prefs),
203+
stopTorDelaySettingAtAppStartup.toLong(),
204+
LibraryPrefs.getControllerDisableStopServiceOnTaskRemovedSetting(prefs),
205+
LibraryPrefs.getControllerBuildConfigDebugSetting(prefs)
206+
)
190207

191-
return builder.build()
192-
// }
208+
TorServiceController.appEventBroadcaster?.let {
209+
(it as MyEventBroadcaster).broadcastLogMessage(
210+
"SampleApp|Application|Process ID: ${Process.myPid()}"
211+
)
212+
}
213+
} catch (e: Exception) {
214+
Toast.makeText(this, e.message, Toast.LENGTH_LONG).show()
215+
}
193216
}
194217
}

0 commit comments

Comments
 (0)