Skip to content

Commit

Permalink
Initial xposed support
Browse files Browse the repository at this point in the history
A lot still needs to be fixed/implemented
- I need to get the wifi info on a different thread, so the UI isn't blocked
- I could probable show more on the wifi info screen
- I need to find a way to show ads
  • Loading branch information
hacker1024 committed Apr 5, 2018
1 parent 6129a53 commit 26b2b0b
Show file tree
Hide file tree
Showing 11 changed files with 271 additions and 38 deletions.
4 changes: 4 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,13 @@ android {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
//noinspection GradleCompatible
implementation 'com.android.support:appcompat-v7:27.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
compileOnly 'de.robv.android.xposed:api:82'
compileOnly 'de.robv.android.xposed:api:82:sources'
implementation 'com.github.kenglxn.QRGen:android:2.4.0'
implementation 'com.crossbowffs.remotepreferences:remotepreferences:0.5'

// START AD SERVICES
implementation('com.mopub:mopub-sdk:4.20.0@aar') {
Expand Down
1 change: 1 addition & 0 deletions app/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
-keep class tk.superl2.xwifi.xposed.** { *; }
19 changes: 18 additions & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,16 @@
android:supportsRtl="true"
android:theme="@style/AppTheme">

<meta-data
android:name="xposedmodule"
android:value="true" />
<meta-data
android:name="xposeddescription"
android:value="Adds an option to share a saved wifi network as a QR code in the system settings" />
<meta-data
android:name="xposedminversion"
android:value="82" />

<meta-data android:name="applovin.sdk.key"
android:value="NaAFA-JFGfuBZTVkWkZi7La8TdiU3vrRU_he-0uEfnPDJwyqdVWms6uPkauoUkDzkvbhvUxTFLnTFiNtDvc4_V" />

Expand All @@ -32,7 +42,9 @@
<activity
android:name=".SettingsActivity"
android:label="@string/title_activity_settings"
android:parentActivityName=".MainActivity">
android:parentActivityName=".MainActivity" tools:ignore="UnusedAttribute"
android:exported="true"
>
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="tk.superl2.xwifi.MainActivity" />
Expand All @@ -45,6 +57,11 @@
<activity android:name="com.mopub.mobileads.MraidVideoPlayerActivity" android:configChanges="keyboardHidden|orientation|screenSize"/>
<activity android:name="com.applovin.adview.AppLovinInterstitialActivity" android:configChanges="orientation|screenSize"/>
<activity android:name="com.applovin.adview.AppLovinConfirmationActivity" android:configChanges="orientation|screenSize"/>

<provider
android:name=".PreferenceProvider"
android:authorities="tk.superl2.xwifi.preferences"
android:exported="true" tools:ignore="ExportedContentProvider" />
</application>

</manifest>
1 change: 1 addition & 0 deletions app/src/main/assets/xposed_init
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
tk.superl2.xwifi.xposed.XposedModule
27 changes: 14 additions & 13 deletions app/src/main/java/tk/superl2/xwifi/MainActivity.kt
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package tk.superl2.xwifi

import android.Manifest
import android.app.AlertDialog
import android.content.Intent
import android.content.SharedPreferences
import android.content.pm.PackageManager
import android.os.AsyncTask
import android.os.Build
import android.os.Bundle
import android.preference.PreferenceManager
import android.support.v4.app.ActivityCompat
import android.support.v4.content.ContextCompat
import android.support.v7.app.AppCompatActivity
import android.support.v7.app.AppCompatDelegate
import android.text.Html
Expand All @@ -18,28 +21,26 @@ import android.widget.ImageView
import android.widget.ProgressBar
import android.widget.Toast
import com.applovin.sdk.AppLovinSdk
import com.mopub.mobileads.MoPubView
import kotlinx.android.synthetic.main.activity_main.*
import net.glxn.qrgen.android.QRCode
import net.glxn.qrgen.core.scheme.Wifi

private const val TAG = "MainActivity"
private const val DEFAULT_QR_GENERATION_RESOLUTION = "300"
private const val QR_CODE_DIALOG_BOTTOM_IMAGE_MARGIN = 0
const val PERMISSION_CODE_GROUP_ADS = 0

internal const val QR_CODE_DIALOG_BOTTOM_IMAGE_MARGIN = 0

class MainActivity: AppCompatActivity() {
// This variable holds an ArrayList of WifiEntry objects that each contain a saved wifi SSID and
// password. It is updated whenever focus returns to the app (onResume).
private lateinit var wifiEntries: ArrayList<WifiEntry>
private val wifiEntrySSIDs = ArrayList<String>()
private lateinit var loadWifiEntriesInBackgroundTask: LoadWifiEntriesInBackground
private lateinit var prefs: SharedPreferences

private lateinit var qrDialog: AlertDialog

override fun onCreate(savedInstanceState: Bundle?) {
PreferenceManager.setDefaultValues(this, R.xml.preferences, false)
prefs = PreferenceManager.getDefaultSharedPreferences(this)
val prefs = PreferenceManager.getDefaultSharedPreferences(this)

setThemeFromSharedPrefs(prefs)
super.onCreate(savedInstanceState)
Expand All @@ -61,7 +62,7 @@ class MainActivity: AppCompatActivity() {
qrCodeView.setImageBitmap(QRCode
.from(Wifi()
.withSsid(wifiEntrySSIDs[position])
.withPsk(wifiEntries[position].getPassword(true))
.withPsk(wifiEntries[position].password)
.withAuthentication(wifiEntries[position].type.asQRCodeAuth()))
.withColor((if (AppCompatDelegate.getDefaultNightMode() != AppCompatDelegate.MODE_NIGHT_YES) 0xFF000000 else 0xFFE0E0E0).toInt(), 0x00000000) //TODO Better colour handling - atm, the colours may be wrong if the theme is set to system or auto.
.withSize(prefs.getString("qr_code_resolution", DEFAULT_QR_GENERATION_RESOLUTION).toInt(), prefs.getString("qr_code_resolution", DEFAULT_QR_GENERATION_RESOLUTION).toInt())
Expand All @@ -78,14 +79,14 @@ class MainActivity: AppCompatActivity() {
builder.setMessage(if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
Html.fromHtml(
"<b>SSID</b>: ${wifiEntries[position].title}<br>" +
(if (wifiEntries[position].getPassword(true) != "") "<b>Password</b>: ${if (wifiEntries[position].type != WifiEntry.Type.WEP) wifiEntries[position].getPassword(true) else wifiEntries[position].getPassword(true).removePrefix("\"").removeSuffix("\"")}<br>" else { "" }) +
(if (wifiEntries[position].password != "") "<b>Password</b>: ${if (wifiEntries[position].type != WifiEntry.Type.WEP) wifiEntries[position].password else wifiEntries[position].password.removePrefix("\"").removeSuffix("\"")}<br>" else { "" }) +
"<b>Type</b>: ${wifiEntries[position].type}",
Html.FROM_HTML_MODE_LEGACY)
} else {
@Suppress("DEPRECATION")
Html.fromHtml(
"<b>SSID</b>: ${wifiEntries[position].title}<br>" +
(if (wifiEntries[position].getPassword(true) != "") "<b>Password</b>: ${if (wifiEntries[position].type != WifiEntry.Type.WEP) wifiEntries[position].getPassword(true) else wifiEntries[position].getPassword(true).removePrefix("\"").removeSuffix("\"")}<br>" else { "" }) +
(if (wifiEntries[position].password != "") "<b>Password</b>: ${if (wifiEntries[position].type != WifiEntry.Type.WEP) wifiEntries[position].password else wifiEntries[position].password.removePrefix("\"").removeSuffix("\"")}<br>" else { "" }) +
"<b>Type</b>: ${wifiEntries[position].type}"
)
}
Expand Down Expand Up @@ -126,14 +127,14 @@ class MainActivity: AppCompatActivity() {
private lateinit var errorDialog: AlertDialog
private lateinit var loadingDialog: AlertDialog

private inner class LoadWifiEntriesInBackground : AsyncTask<Unit, Unit, Unit>() {
private inner class LoadWifiEntriesInBackground: AsyncTask<Unit, Unit, Unit>() {
override fun onPreExecute() {
val loadingDialogBuilder = AlertDialog.Builder(this@MainActivity)
loadingDialogBuilder.setCancelable(false)
loadingDialogBuilder.setMessage(R.string.wifi_loading_message)
loadingDialogBuilder.setView(ProgressBar(this@MainActivity))
loadingDialog = loadingDialogBuilder.create()
loadingDialog.show()
runOnUiThread { loadingDialog.show() }
}

override fun doInBackground(vararg params: Unit?) {
Expand Down Expand Up @@ -194,7 +195,7 @@ class MainActivity: AppCompatActivity() {
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
return when (item!!.itemId) {
R.id.settingsItem -> {
startActivity(Intent(this, SettingsActivity::class.java))
startActivity(Intent(this, SettingsActivity::class.java).putExtra("xposed", false))
true
}
else -> super.onOptionsItemSelected(item)
Expand Down
12 changes: 12 additions & 0 deletions app/src/main/java/tk/superl2/xwifi/PreferenceProvider.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package tk.superl2.xwifi

class PreferenceProvider: com.crossbowffs.remotepreferences.RemotePreferenceProvider("tk.superl2.xwifi.preferences", arrayOf("tk.superl2.xwifi_preferences")) {
override fun checkAccess(prefName: String, prefKey: String, write: Boolean): Boolean {
if (write) return false
return when (prefKey) {
"theme" -> false
"qr_code_resolution" -> true
else -> false
}
}
}
33 changes: 18 additions & 15 deletions app/src/main/java/tk/superl2/xwifi/SettingsActivity.kt
Original file line number Diff line number Diff line change
@@ -1,32 +1,28 @@
package tk.superl2.xwifi

import android.content.SharedPreferences
import android.os.Build
import android.os.Bundle
import android.preference.Preference
import android.preference.PreferenceActivity
import android.preference.PreferenceFragment
import android.preference.PreferenceManager
import android.support.v7.app.AppCompatActivity
import android.support.v7.app.AppCompatDelegate
import android.widget.Toast

internal const val DEFAULT_QR_GENERATION_RESOLUTION = "300"

/**
* A [PreferenceActivity] that presents a set of application settings. On
* handset devices, settings are presented as a single list. On tablets,
* settings are split by category, with category headers shown to the left of
* the list of settings.
*
* See [Android Design: Settings](http://developer.android.com/design/patterns/settings.html)
* for design guidelines and the [Settings API Guide](http://developer.android.com/guide/topics/ui/settings.html)
* for more information on developing a Settings UI.
*/
class SettingsActivity: AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
PreferenceManager.setDefaultValues(this, R.xml.preferences, false)

if (intent.extras.getBoolean("xposed")) {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
} else {
setThemeFromSharedPrefs(PreferenceManager.getDefaultSharedPreferences(this))
}

super.onCreate(savedInstanceState)

// Display the fragment as the main context
fragmentManager.beginTransaction().replace(android.R.id.content, SettingsFragment()).commit()
fragmentManager.beginTransaction().replace(android.R.id.content, if (intent.extras.getBoolean("xposed")) XposedSettingsFragment() else SettingsFragment()).commit()
}
}

Expand All @@ -44,4 +40,11 @@ class SettingsFragment: PreferenceFragment() {
true
}
}
}

class XposedSettingsFragment: PreferenceFragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
addPreferencesFromResource(R.xml.xposed_preferences)
}
}
32 changes: 24 additions & 8 deletions app/src/main/java/tk/superl2/xwifi/WifiDataUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,15 @@ import java.io.IOException
import java.io.InputStreamReader
import java.util.*

const val ANDROID_SECURITY_NONE = 0
const val ANDROID_SECURITY_WEP = 1
const val ANDROID_SECURITY_PSK = 2
const val ANDROID_SECURITY_EAP = 3
const val ANDROID_PSK_UNKNOWN = 0
const val ANDROID_PSK_WPA = 1
const val ANDROID_PSK_WPA2 = 2
const val ANDROID_PSK_WPA_WPA2 = 3

data class WifiEntry(var title: String = "", var password: String = "", var type: Type = Type.NONE) {
enum class Type {
WPA {
Expand All @@ -28,16 +37,23 @@ data class WifiEntry(var title: String = "", var password: String = "", var type
};

abstract fun asQRCodeAuth(): Wifi.Authentication
}

fun getPassword(showAll: Boolean): String =
if (showAll) {
password
} else {
val fill = CharArray(password.length)
Arrays.fill(fill, '*')
String(fill)
companion object {
fun fromAndroidSecurityInt(security: Int, pskType: Int): WifiEntry.Type = when (security) {
ANDROID_SECURITY_WEP -> WEP
ANDROID_SECURITY_PSK -> {
when (pskType) {
ANDROID_PSK_WPA -> WPA
ANDROID_PSK_WPA2 -> WPA
ANDROID_PSK_WPA_WPA2 -> WPA
else -> WPA
}
}
// ANDROID_SECURITY_EAP -> EAP
else -> NONE
}
}
}
}

private const val mOreoLocation = "/data/misc/wifi/WifiConfigStore.xml"
Expand Down
Loading

0 comments on commit 26b2b0b

Please sign in to comment.