Skip to content

Commit 118fde9

Browse files
committed
Convert new wifi entry loader class to kotlin
1 parent fad08b4 commit 118fde9

File tree

4 files changed

+197
-201
lines changed

4 files changed

+197
-201
lines changed

app/src/main/java/tk/superl2/xwifi/MainActivity.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ class MainActivity: Activity() {
103103
if (::wifiEntries.isInitialized) wifiEntries.clear()
104104
wifiEntrySSIDs.clear()
105105
try {
106-
wifiEntries = WifiEntryLoaderJava.readOreoFile()
106+
wifiEntries = WifiEntryLoader.readOreoFile()
107107
wifiEntries.removeIf { it.type == WifiEntry.Type.ENTERPRISE }
108108
wifiEntries.mapTo(wifiEntrySSIDs) { it.title }
109109
Log.v(TAG, "Wifi entries loaded.")
Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
package tk.superl2.xwifi
2+
3+
import android.util.Log
4+
import android.util.Xml
5+
import org.xmlpull.v1.XmlPullParser
6+
import org.xmlpull.v1.XmlPullParserException
7+
import java.io.IOException
8+
import java.util.*
9+
10+
object WifiEntryLoader {
11+
private const val mOreoLocation = "/data/misc/wifi/WifiConfigStore.xml"
12+
13+
@Throws(XmlPullParserException::class, IOException::class)
14+
private fun readNetworkList(parser: XmlPullParser): ArrayList<WifiEntry> {
15+
val result = ArrayList<WifiEntry>()
16+
parser.require(XmlPullParser.START_TAG, null, "NetworkList")
17+
var doLoop = true
18+
while (doLoop) {
19+
try {
20+
parser.next()
21+
var tagName: String? = parser.name
22+
if (tagName == null) {
23+
tagName = ""
24+
}
25+
doLoop = !tagName.equals("NetworkList", ignoreCase = true)
26+
if (parser.eventType != XmlPullParser.START_TAG) {
27+
continue
28+
}
29+
30+
if (tagName == "Network") {
31+
val newWifi = readNetworkEntry(parser)
32+
if (newWifi.title.isNotEmpty()) {
33+
result.add(newWifi)
34+
}
35+
} else {
36+
skip(parser)
37+
}
38+
} catch (e: Exception) {
39+
Log.e("LoadData.NetworkList", e.message)
40+
doLoop = false
41+
}
42+
43+
}
44+
return result
45+
}
46+
47+
// Parses a "Network" entry
48+
@Throws(XmlPullParserException::class, IOException::class)
49+
private fun readNetworkEntry(parser: XmlPullParser): WifiEntry {
50+
parser.require(XmlPullParser.START_TAG, null, "Network")
51+
var result = WifiEntry()
52+
while (parser.next() != XmlPullParser.END_TAG) {
53+
if (parser.eventType != XmlPullParser.START_TAG) {
54+
continue
55+
}
56+
val tagName = parser.name
57+
// Starts by looking for the entry tag
58+
when (tagName) {
59+
"WifiConfiguration" -> result = readWiFiConfig(parser, result)
60+
"WifiEnterpriseConfiguration" -> result.type = WifiEntry.Type.ENTERPRISE
61+
else -> skip(parser)
62+
}
63+
}
64+
return result
65+
}
66+
67+
// Parses a "WifiConfiguration" entry
68+
@Throws(XmlPullParserException::class, IOException::class)
69+
private fun readWiFiConfig(parser: XmlPullParser, result: WifiEntry): WifiEntry {
70+
try {
71+
while (parser.next() != XmlPullParser.END_TAG) {
72+
if (parser.eventType != XmlPullParser.START_TAG) {
73+
continue
74+
}
75+
val tagName = parser.name
76+
val name = parser.getAttributeValue(null, "name")
77+
if (name == "SSID" && !tagName.equals("null", ignoreCase = true)) {
78+
result.title = readTag(parser, tagName)
79+
} else if (name == "PreSharedKey" && !tagName.equals("null", ignoreCase = true)) {
80+
val newPwd = readTag(parser, tagName)
81+
if (newPwd.isNotEmpty()) {
82+
result.password = newPwd
83+
result.type = WifiEntry.Type.WPA
84+
}
85+
} else if (name == "WEPKeys" && !tagName.equals("null", ignoreCase = true)) {
86+
result.type = WifiEntry.Type.WEP
87+
if (tagName.equals("string-array", ignoreCase = true)) {
88+
try {
89+
val numQty = Integer.parseInt(parser.getAttributeValue(null, "num"))
90+
var loopQty = 0
91+
while (parser.next() != XmlPullParser.END_DOCUMENT && loopQty < numQty) {
92+
val innerTagName = parser.name
93+
if (innerTagName != null && innerTagName.equals("item", ignoreCase = true)) {
94+
loopQty++
95+
val newPwd = parser.getAttributeValue(null, "value")
96+
if (newPwd.isNotEmpty()) {
97+
result.password = newPwd
98+
}
99+
}
100+
}
101+
} catch (error: Exception) {
102+
parser.name
103+
}
104+
105+
} else {
106+
val newPwd = readTag(parser, tagName)
107+
if (newPwd.isNotEmpty()) {
108+
result.password = readTag(parser, tagName)
109+
}
110+
}
111+
} else {
112+
skip(parser)
113+
}
114+
}
115+
} catch (error: Exception) {
116+
Log.e("LoadData.readWiFiConfig", error.message + "\n\nParser: " + parser.text)
117+
}
118+
119+
return result
120+
}
121+
122+
// Return the text for a specified tag.
123+
@Throws(IOException::class, XmlPullParserException::class)
124+
private fun readTag(parser: XmlPullParser, tagName: String): String {
125+
parser.require(XmlPullParser.START_TAG, null, tagName)
126+
var result = ""
127+
if (parser.next() == XmlPullParser.TEXT) {
128+
result = parser.text
129+
parser.nextTag()
130+
}
131+
parser.require(XmlPullParser.END_TAG, null, tagName)
132+
if (tagName.equals("string", ignoreCase = true) && Character.toString(result[0]) == "\"") {
133+
result = result.substring(1, result.length - 1)
134+
}
135+
return result
136+
}
137+
138+
// Skips tags the parser isn't interested in. Uses depth to handle nested tags. i.e.,
139+
// if the next tag after a START_TAG isn't a matching END_TAG, it keeps going until it
140+
// finds the matching END_TAG (as indicated by the value of "depth" being 0).
141+
@Throws(XmlPullParserException::class, IOException::class)
142+
private fun skip(parser: XmlPullParser) {
143+
if (parser.eventType != XmlPullParser.START_TAG) {
144+
throw IllegalStateException()
145+
}
146+
var depth = 1
147+
while (depth != 0) {
148+
when (parser.next()) {
149+
XmlPullParser.END_TAG -> depth--
150+
XmlPullParser.START_TAG -> depth++
151+
}
152+
}
153+
}
154+
155+
fun readOreoFile(): ArrayList<WifiEntry> {
156+
val result = ArrayList<WifiEntry>()
157+
try {
158+
val suOreoProcess = Runtime.getRuntime().exec("su")
159+
val suOreoProcessOutputStream = suOreoProcess.outputStream
160+
suOreoProcessOutputStream.write("/system/bin/cat $mOreoLocation\n".toByteArray())
161+
suOreoProcessOutputStream.write("exit\n".toByteArray())
162+
suOreoProcessOutputStream.flush()
163+
suOreoProcessOutputStream.close()
164+
try {
165+
suOreoProcess.waitFor()
166+
} catch (e: InterruptedException) {
167+
e.printStackTrace()
168+
}
169+
170+
val parser = Xml.newPullParser()
171+
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false)
172+
parser.setInput(suOreoProcess.inputStream, "UTF-8")
173+
while (parser.next() != XmlPullParser.END_DOCUMENT) {
174+
if (parser.eventType != XmlPullParser.START_TAG) {
175+
continue
176+
}
177+
if (parser.name.equals("NetworkList", ignoreCase = true)) {
178+
// Process the <Network> entries in the list
179+
result.addAll(readNetworkList(parser))
180+
}
181+
}
182+
} catch (e: IOException) {
183+
e.printStackTrace()
184+
} catch (e: XmlPullParserException) {
185+
e.printStackTrace()
186+
} finally {
187+
return if (result.isNotEmpty()) {
188+
result
189+
} else {
190+
throw WifiUnparseableException()
191+
}
192+
}
193+
}
194+
}
195+
196+
class WifiUnparseableException(message: String = "Wifi list could not be parsed."): Exception(message)

app/src/main/java/tk/superl2/xwifi/WifiEntryLoaderJava.java

Lines changed: 0 additions & 189 deletions
This file was deleted.

0 commit comments

Comments
 (0)