Support resetting credentials

This commit is contained in:
Mygod
2018-01-13 16:45:23 +08:00
parent 5e97e3d9ae
commit 86013c93fb
3 changed files with 57 additions and 9 deletions

View File

@@ -68,14 +68,14 @@ class RepeaterFragment : Fragment(), ServiceConnection, Toolbar.OnMenuItemClickL
class ClientViewHolder(val binding: ListitemClientBinding) : RecyclerView.ViewHolder(binding.root) class ClientViewHolder(val binding: ListitemClientBinding) : RecyclerView.ViewHolder(binding.root)
inner class ClientAdapter : RecyclerView.Adapter<ClientViewHolder>() { inner class ClientAdapter : RecyclerView.Adapter<ClientViewHolder>() {
private var owner: WifiP2pDevice? = null private var owner: WifiP2pDevice? = null
private lateinit var clients: MutableCollection<WifiP2pDevice> private lateinit var clients: Collection<WifiP2pDevice>
private lateinit var arpCache: Map<String, String> private lateinit var arpCache: Map<String, String>
fun fetchClients() { fun fetchClients() {
val binder = binder val binder = binder
if (binder?.active == true) { if (binder?.active == true) {
owner = binder.service.group.owner owner = binder.service.group?.owner
clients = binder.service.group.clientList clients = binder.service.group?.clientList ?: emptyList()
arpCache = NetUtils.arp(binder.service.routing?.downstream) arpCache = NetUtils.arp(binder.service.routing?.downstream)
} else owner = null } else owner = null
notifyDataSetChanged() // recreate everything notifyDataSetChanged() // recreate everything
@@ -162,6 +162,15 @@ class RepeaterFragment : Fragment(), ServiceConnection, Toolbar.OnMenuItemClickL
dialog.show() dialog.show()
true true
} else false } else false
R.id.resetGroup -> {
AlertDialog.Builder(context!!)
.setTitle("Reset credentials")
.setMessage("Android system will generate new network name and password next time repeater is activated. This is irreversible.")
.setPositiveButton("Reset", { _, _ -> binder?.resetCredentials() })
.setNegativeButton(android.R.string.cancel, null)
.show()
true
}
else -> false else -> false
} }
} }

View File

@@ -25,7 +25,9 @@ class RepeaterService : Service(), WifiP2pManager.ChannelListener, VpnListener.C
companion object { companion object {
const val CHANNEL = "repeater" const val CHANNEL = "repeater"
const val ACTION_STATUS_CHANGED = "be.mygod.vpnhotspot.RepeaterService.STATUS_CHANGED" const val ACTION_STATUS_CHANGED = "be.mygod.vpnhotspot.RepeaterService.STATUS_CHANGED"
const val KEY_NET_ID = "netId"
private const val TAG = "RepeaterService" private const val TAG = "RepeaterService"
private const val TEMPORARY_NET_ID = -1
/** /**
* Matches the output of dumpsys wifip2p. This part is available since Android 4.2. * Matches the output of dumpsys wifip2p. This part is available since Android 4.2.
@@ -44,12 +46,32 @@ class RepeaterService : Service(), WifiP2pManager.ChannelListener, VpnListener.C
* *
* Source: https://android.googlesource.com/platform/frameworks/base/+/android-4.3_r0.9/wifi/java/android/net/wifi/p2p/WifiP2pManager.java#958 * Source: https://android.googlesource.com/platform/frameworks/base/+/android-4.3_r0.9/wifi/java/android/net/wifi/p2p/WifiP2pManager.java#958
*/ */
private val startWpsMethod = WifiP2pManager::class.java.getDeclaredMethod("startWps", private val startWps = WifiP2pManager::class.java.getDeclaredMethod("startWps",
WifiP2pManager.Channel::class.java, WpsInfo::class.java, WifiP2pManager.ActionListener::class.java) WifiP2pManager.Channel::class.java, WpsInfo::class.java, WifiP2pManager.ActionListener::class.java)
private fun WifiP2pManager.startWps(c: WifiP2pManager.Channel, wps: WpsInfo, private fun WifiP2pManager.startWps(c: WifiP2pManager.Channel, wps: WpsInfo,
listener: WifiP2pManager.ActionListener) { listener: WifiP2pManager.ActionListener) {
startWpsMethod.invoke(this, c, wps, listener) startWps.invoke(this, c, wps, listener)
} }
/**
* Available since Android 4.2.
*
* Source: https://android.googlesource.com/platform/frameworks/base/+/android-4.2_r1/wifi/java/android/net/wifi/p2p/WifiP2pManager.java#1353
*/
private val deletePersistentGroup = WifiP2pManager::class.java.getDeclaredMethod("deletePersistentGroup",
WifiP2pManager.Channel::class.java, Int::class.java, WifiP2pManager.ActionListener::class.java)
private fun WifiP2pManager.deletePersistentGroup(c: WifiP2pManager.Channel, netId: Int,
listener: WifiP2pManager.ActionListener) {
deletePersistentGroup.invoke(this, c, netId, listener)
}
/**
* Available since Android 4.2.
*
* Source: https://android.googlesource.com/platform/frameworks/base/+/android-4.2_r1/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java#253
*/
private val getNetworkId = WifiP2pGroup::class.java.getDeclaredMethod("getNetworkId")
private val WifiP2pGroup.netId get() = getNetworkId.invoke(this) as Int
} }
enum class Status { enum class Status {
@@ -80,6 +102,17 @@ class RepeaterService : Service(), WifiP2pManager.ChannelListener, VpnListener.C
fun shutdown() { fun shutdown() {
if (status == Status.ACTIVE) removeGroup() if (status == Status.ACTIVE) removeGroup()
} }
fun resetCredentials() {
val netId = app.pref.getInt(KEY_NET_ID, TEMPORARY_NET_ID)
if (netId == TEMPORARY_NET_ID) return
p2pManager.deletePersistentGroup(channel, netId, object : WifiP2pManager.ActionListener {
override fun onSuccess() = Toast.makeText(this@RepeaterService,
"Credentials reset.", Toast.LENGTH_SHORT).show()
override fun onFailure(reason: Int) = Toast.makeText(this@RepeaterService,
"Failed to reset credentials (reason: ${formatReason(reason)})", Toast.LENGTH_SHORT).show()
})
}
} }
private val handler = Handler() private val handler = Handler()
@@ -89,8 +122,11 @@ class RepeaterService : Service(), WifiP2pManager.ChannelListener, VpnListener.C
if (_channel == null) onChannelDisconnected() if (_channel == null) onChannelDisconnected()
return _channel!! return _channel!!
} }
lateinit var group: WifiP2pGroup var group: WifiP2pGroup? = null
private set private set(value) {
field = value
if (value != null) app.pref.edit().putInt(KEY_NET_ID, value.netId).apply()
}
private val binder = HotspotBinder() private val binder = HotspotBinder()
private var receiverRegistered = false private var receiverRegistered = false
private val receiver = broadcastReceiver { _, intent -> private val receiver = broadcastReceiver { _, intent ->
@@ -107,8 +143,8 @@ class RepeaterService : Service(), WifiP2pManager.ChannelListener, VpnListener.C
} }
private val onVpnUnavailable = Runnable { startFailure("VPN unavailable") } private val onVpnUnavailable = Runnable { startFailure("VPN unavailable") }
val ssid get() = if (status == Status.ACTIVE) group.networkName else null val ssid get() = if (status == Status.ACTIVE) group?.networkName else null
val password get() = if (status == Status.ACTIVE) group.passphrase else null val password get() = if (status == Status.ACTIVE) group?.passphrase else null
private var upstream: String? = null private var upstream: String? = null
var routing: Routing? = null var routing: Routing? = null

View File

@@ -4,4 +4,7 @@
<item <item
android:id="@+id/wps" android:id="@+id/wps"
android:title="WPS"/> android:title="WPS"/>
<item
android:id="@+id/resetGroup"
android:title="Reset credentials"/>
</menu> </menu>