Skip to content

Commit

Permalink
Merge pull request #11 from Jolanrensen/usingSecureSettingsPermission
Browse files Browse the repository at this point in the history
v3.7:
  • Loading branch information
Jolanrensen authored Oct 29, 2019
2 parents 09b6c1b + c9c3030 commit 798b121
Show file tree
Hide file tree
Showing 16 changed files with 209 additions and 90 deletions.
4 changes: 2 additions & 2 deletions mobile/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ android {
applicationId "nl.jolanrensen.permanentproxy"
minSdkVersion 23
targetSdkVersion 29
versionCode 12
versionName "3.5"
versionCode 14
versionName "3.7"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
Expand Down
69 changes: 39 additions & 30 deletions mobile/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
@@ -1,36 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<TextView
android:id="@+id/textView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:text="@string/wrapper_app"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<TextView
android:id="@+id/textView2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp"
android:text="@string/instructions"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/textView"
app:layout_constraintVertical_bias="0.0" />

</androidx.constraintlayout.widget.ConstraintLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="16dp">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">

<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:text="@string/wrapper_app"
android:textIsSelectable="true" />

<TextView
android:id="@+id/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:text="@string/instructions"
android:textIsSelectable="true" />


<TextView
android:id="@+id/textView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/old_watch"
android:textIsSelectable="true" />
</LinearLayout>

</ScrollView>

</RelativeLayout>
3 changes: 2 additions & 1 deletion mobile/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<resources>
<string name="app_name">Permanent Proxy</string>
<string name="wrapper_app">This app is just a phone companion of Permanent Proxy. Please install Permanent Proxy from the Play Store on you Wear OS watch.</string>
<string name="wrapper_app">This app is just a phone companion of Permanent Proxy. Please install Permanent Proxy from the Play Store on you Wear OS watch. The app can be found in the \"Apps on your Phone\" section.</string>
<string name="instructions"><![CDATA[Please read carefully:\nTo get started, first enable the Developer Options of your watch, which can be achieved by going to Settings -> System -> About and tap the Build number until you are a \"developer\".\nNext, go to Settings -> Developer options and enable \"ADB debugging\" and \"Debug over Bluetooth\".\nFinally start up Permanent Proxy, request permission and press \"Allow\" or \"Always allow this Computer\" if prompted.\nAfter the app has gotten permission, ADB can be turned off again unless you want to disable the proxy.\n\nNow you can get started! Simply enter a proxy address and port, enable it and you\'re done! If you reboot, the proxy will remain.\n\nProxy services can be found online and can be from any country. However, do make sure your proxy works and you completely trust the proxy you chose before you enter it! All the data of your watch might be sent through that proxy, even sensitive data, so act at your own risk.]]></string>
<string name="old_watch">Some older watches are not powerful enough to get Secure Settings permission by itself using my method. If this is the case for your watch, you will need a PC to grant Permanent Proxy permission. The instructions are also available in the app description.\n\nFirst make sure to connect your watch to your PC via ADB. You can Google how to do this, there are lots of tutorials. When your watch is connected, use the command \n\nadb shell pm grant nl.jolanrensen.permanentproxy android.permission.WRITE_SECURE_SETTINGS\n\nto give Permanent Proxy the permissions needed to turn on/edit the proxy.\n\nTo turn off the proxy, connect to your PC in the same manner as before, but now you will need the following command: \n\nadb shell settings delete global http_proxy; adb shell settings delete global global_http_proxy_host; adb shell settings delete global global_http_proxy_port; adb shell settings delete global global_http_proxy_exclusion_list; adb shell settings delete global global_proxy_pac_url; adb shell reboot</string>
</resources>
4 changes: 2 additions & 2 deletions wear/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ android {
applicationId "nl.jolanrensen.permanentproxy"
minSdkVersion 23
targetSdkVersion 29
versionCode 12
versionName "3.5"
versionCode 14
versionName "3.7"
}
buildTypes {
release {
Expand Down
Binary file modified wear/release/mobile-release.apk
Binary file not shown.
Binary file modified wear/release/wear-release.aab
Binary file not shown.
Binary file modified wear/release/wear-release.apk
Binary file not shown.
11 changes: 6 additions & 5 deletions wear/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<uses-permission
android:name="android.permission.WRITE_SECURE_SETTINGS"
tools:ignore="ProtectedPermissions" />
<uses-permission android:name="com.android.vending.BILLING"/>
<uses-permission android:name="com.android.vending.BILLING" />

<application
android:allowBackup="true"
Expand All @@ -33,14 +33,15 @@
android:name="com.google.android.wearable.standalone"
android:value="true" />

<activity
android:name=".OldWatchActivity"
android:label="@string/title_activity_old_watch"/>
<activity
android:name=".DonateActivity"
android:label="@string/title_activity_donate">
</activity>
android:label="@string/title_activity_donate"/>
<activity
android:name=".EnableADBBluetoothActivity"
android:label="@string/title_activity_enable_adbbluetooth">
</activity>
android:label="@string/title_activity_enable_adbbluetooth"/>
<activity
android:name=".MainActivity"
android:label="@string/app_name">
Expand Down
21 changes: 20 additions & 1 deletion wear/src/main/java/nl/jolanrensen/permanentproxy/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import nl.jolanrensen.permanentproxy.Constants.currentProxy
import nl.jolanrensen.permanentproxy.Constants.getCurrentIP
import nl.jolanrensen.permanentproxy.Constants.logD
import nl.jolanrensen.permanentproxy.Constants.logE
import nl.jolanrensen.permanentproxy.Constants.startProxy
import nl.jolanrensen.permanentproxy.Constants.stopProxy
Expand Down Expand Up @@ -87,15 +88,21 @@ class MainActivity : WearableActivity() {
startActivityForResult(
Intent(this, RequestPermissionActivity::class.java),
PERMISSION

)
onPause()
}

donate.setOnClickListener {
startActivity(
Intent(this, DonateActivity::class.java)
)
}

old_watch.setOnClickListener {
startActivity(
Intent(this, OldWatchActivity::class.java)
)
}
}

private fun setupStatus(wait: Boolean = false): Boolean {
Expand Down Expand Up @@ -252,6 +259,17 @@ class MainActivity : WearableActivity() {
}
}

override fun onPause() {
super.onPause()
logD("onPause")
}

override fun onResume() {
super.onResume()
logD("onResume")
}


private fun showSoftKeyboard(view: View) {
if (view.requestFocus()) {
getSystemService<InputMethodManager>()?.apply {
Expand All @@ -272,6 +290,7 @@ class MainActivity : WearableActivity() {
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
onResume()
when {
requestCode == PERMISSION && resultCode == RESULT_OK -> {
continueSetup()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package nl.jolanrensen.permanentproxy

import android.os.Bundle
import android.support.wearable.activity.WearableActivity

class OldWatchActivity : WearableActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_old_watch)

// Enables Always-on
setAmbientEnabled()
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package nl.jolanrensen.permanentproxy

import android.app.Activity
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Bundle
import android.support.wearable.activity.WearableActivity
import androidx.core.view.isVisible
import kotlinx.android.synthetic.main.activity_request_permission.*
import nl.jolanrensen.permanentproxy.Constants.logE
import nl.jolanrensen.permanentproxy.Constants.toastLong
Expand Down Expand Up @@ -65,11 +67,19 @@ class RequestPermissionActivity : WearableActivity() {
// useless loading bar to show google the app is doing something
thread(start = true) {
var s = 0
while (s <= 25 && !stop) {
loading_bar.progress = ((s / 25f) * 100f).toInt()
while (s <= 35 && !stop) {
loading_bar.progress = ((s / 35f) * 100f).toInt()
s++
Thread.sleep(1000)
}
runOnUiThread {
too_long.isVisible = true
too_long.setOnClickListener {
startActivity(Intent(this, OldWatchActivity::class.java))
finish()
}
}

}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,17 @@ import com.tananaev.adblib.AdbBase64
import com.tananaev.adblib.AdbConnection
import com.tananaev.adblib.AdbCrypto
import com.tananaev.adblib.AdbStream
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import java.io.File
import java.io.IOException
import java.io.UnsupportedEncodingException
import java.lang.Thread.sleep
import java.net.ConnectException
import java.net.NoRouteToHostException
import java.net.Socket
import java.net.UnknownHostException
import java.security.NoSuchAlgorithmException
import java.security.spec.InvalidKeySpecException
import kotlin.concurrent.thread

/**
* Created by Jolan Rensen on 21-2-2017.
Expand Down Expand Up @@ -126,7 +125,10 @@ constructor(
if (ctrlC) stream.write(byteArrayOf(0x03))
stream.write(command + '\n')
} catch (e: IOException) {
throw IOException("Couldn't write command, stream fails while sending data, try without CTRL+C", e)
throw IOException(
"Couldn't write command, stream fails while sending data, try without CTRL+C",
e
)
} catch (e: InterruptedException) {
throw Exception("Couldn't write command, unable to wait to send data", e)
}
Expand All @@ -137,7 +139,7 @@ constructor(
var timer = 0

logD("Getting responses...")
GlobalScope.launch {
thread(start = true) {
while (!done) {
try {
timer = 0
Expand All @@ -152,53 +154,51 @@ constructor(
}
}

GlobalScope.launch {
// the timer resets on each response and when it reached the limit, it stops reading and continues with the rest
while (!done) {
delay(1)
timer++
if (timer >= timeout) done = true
}
// the timer resets on each response and when it reached the limit, it stops reading and continues with the rest
while (!done) {
sleep(1)
timer++
if (timer >= timeout) done = true
}

logD("response:\n$responses")

logD("response:\n$responses")
// Trying to split the response on newlines, not waterproof
splitResponses = ArrayList()
for (item in responses.split("\\n".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()) {
splitResponses!!.add(item.trim { it <= ' ' })
}

// Trying to split the response on newlines, not waterproof
splitResponses = ArrayList()
for (item in responses.split("\\n".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()) {
splitResponses!!.add(item.trim { it <= ' ' })
logD("Sending close command and waiting for stream to close")
stream.close()
thread(start = true) {
sleep(10000)
if (!stream.isClosed)
throw Exception("Stream didn't close after 10 seconds waiting")
}
thread(start = true) {
while (!stream.isClosed) {
sleep(1)
}
logD("Stream closed, closing Adb...")

logD("Sending close command and waiting for stream to close")
stream.close()
GlobalScope.launch {
delay(10000)
if (!stream.isClosed)
throw Exception("Stream didn't close after 10 seconds waiting")
try {
adb.close()
} catch (e: IOException) {
throw IOException("Couldn't close ADB connection socket", e)
}
thread(start = true) {
sleep(10000)
if (!sock.isClosed)
throw Exception("ADB connection socket didn't close after 10 seconds waiting")
}
GlobalScope.launch {
while (!stream.isClosed) {
delay(1)
}
logD("Stream closed, closing Adb...")

try {
adb.close()
} catch (e: IOException) {
throw IOException("Couldn't close ADB connection socket", e)
}
GlobalScope.launch {
delay(10000)
if (!sock.isClosed)
throw Exception("ADB connection socket didn't close after 10 seconds waiting")
}
GlobalScope.launch {
while (!sock.isClosed) {
delay(1)
}
logD("ADB connection socket closed")
callBack(splitResponses)
}
while (!sock.isClosed) {
sleep(1)
}
logD("ADB connection socket closed")
callBack(splitResponses)

}
}

Expand Down
Loading

0 comments on commit 798b121

Please sign in to comment.