Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Android Studio
.idea/
*.iml
.gradle/
build/
captures/

# OS generated files
.DS_Store
Thumbs.db

# Kotlin/Android specific
*.class
*.log
*.apk
*.aar
*.dex
*.module

# Dependency directories
/node_modules
/jspm_packages

# Gradle
gradle/
gradlew
gradlew.bat

# Local configuration file
local.properties

# Log files
*.log

# Android Studio Navigation editor temp files
.navigation/

# Android Studio captures folder
/captures

# Intellij
*.ipr
*.iws

# External native build folder generated in Android Studio 2.2 and later
.externalNativeBuild
.cxx/

# Keystore files
*.jks
*.keystore

# Google Services (e.g. APIs or Firebase)
google-services.json

# Lint
lint/intermediates/
lint/generated/
lint/outputs/
lint/tmp/
lint/reports/
43 changes: 43 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
plugins {
id 'com.android.application'
id 'kotlin-android'
}

android {
compileSdkVersion 30
defaultConfig {
applicationId "com.wifiscanner"
minSdkVersion 29
targetSdkVersion 30
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
}

dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:1.5.21"
implementation 'androidx.core:core-ktx:1.6.0'
implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'com.google.android.material:material:1.4.0'

// Testing dependencies
testImplementation 'junit:junit:4.13.2'
testImplementation 'org.mockito:mockito-core:3.11.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}
14 changes: 14 additions & 0 deletions src/main/kotlin/com/wifiscanner/models/WiFiSecurity.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.wifiscanner.models

/**
* Represents the security type of a WiFi network.
*
* @property type The human-readable security type
* @property description A detailed description of the security type
* @property level A numeric representation of security strength (higher is more secure)
*/
data class WiFiSecurityType(
val type: String,
val description: String,
val level: Int
)
72 changes: 72 additions & 0 deletions src/main/kotlin/com/wifiscanner/utils/WiFiSecurityMapper.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package com.wifiscanner.utils

import com.wifiscanner.models.WiFiSecurityType

/**
* Utility class for mapping WiFi network capabilities to security types.
*/
object WiFiSecurityMapper {
/**
* Maps raw network capabilities to a WiFiSecurityType.
*
* @param capabilities Raw network capabilities string
* @return WiFiSecurityType representing the network's security
*/
fun mapSecurityType(capabilities: String?): WiFiSecurityType {
return when {
capabilities.isNullOrBlank() -> WiFiSecurityType(
"Unknown",
"Unable to determine network security",
0
)
capabilities.contains("WPA3", ignoreCase = true) -> WiFiSecurityType(
"WPA3",
"Most advanced WiFi security protocol",
5
)
capabilities.contains("WPA2", ignoreCase = true) -> WiFiSecurityType(
"WPA2",
"Strong encryption with improved security over WPA",
4
)
capabilities.contains("WPA", ignoreCase = true) -> WiFiSecurityType(
"WPA",
"Older security protocol with moderate protection",
3
)
capabilities.contains("WEP", ignoreCase = true) -> WiFiSecurityType(
"WEP",
"Weak and outdated security protocol",
1
)
capabilities.contains("Open", ignoreCase = true) -> WiFiSecurityType(
"Open",
"No encryption, completely unsecured network",
0
)
else -> WiFiSecurityType(
"Other",
"Unrecognized security type",
2
)
}
}

/**
* Generates a color based on the security level.
*
* @param securityType WiFiSecurityType to determine color for
* @return Color resource ID representing security level
*/
fun getSecurityColor(securityType: WiFiSecurityType): Int {
return when (securityType.level) {
0 -> android.R.color.holo_red_dark // Open/No Security
1 -> android.R.color.holo_red_light // Very Weak
2 -> android.R.color.holo_orange_dark // Weak
3 -> android.R.color.holo_orange_light // Moderate
4 -> android.R.color.holo_green_light // Strong
5 -> android.R.color.holo_green_dark // Most Secure
else -> android.R.color.darker_gray // Unknown
}
}
}
57 changes: 57 additions & 0 deletions src/test/kotlin/com/wifiscanner/utils/WiFiSecurityMapperTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package com.wifiscanner.utils

import com.wifiscanner.models.WiFiSecurityType
import org.junit.Assert.*
import org.junit.Test

class WiFiSecurityMapperTest {

@Test
fun `mapSecurityType should return WPA3 for WPA3 capabilities`() {
val capabilities = "[WPA3-PSK-CCMP]"
val result = WiFiSecurityMapper.mapSecurityType(capabilities)

assertEquals("WPA3", result.type)
assertEquals("Most advanced WiFi security protocol", result.description)
assertEquals(5, result.level)
}

@Test
fun `mapSecurityType should return WPA2 for WPA2 capabilities`() {
val capabilities = "[WPA2-PSK-CCMP]"
val result = WiFiSecurityMapper.mapSecurityType(capabilities)

assertEquals("WPA2", result.type)
assertEquals("Strong encryption with improved security over WPA", result.description)
assertEquals(4, result.level)
}

@Test
fun `mapSecurityType should return Open for open network`() {
val capabilities = ""
val result = WiFiSecurityMapper.mapSecurityType(capabilities)

assertEquals("Open", result.type)
assertEquals("No encryption, completely unsecured network", result.description)
assertEquals(0, result.level)
}

@Test
fun `mapSecurityType should return Unknown for null capabilities`() {
val capabilities = null
val result = WiFiSecurityMapper.mapSecurityType(capabilities)

assertEquals("Unknown", result.type)
assertEquals("Unable to determine network security", result.description)
assertEquals(0, result.level)
}

@Test
fun `getSecurityColor returns correct color for different security levels`() {
val openSecurity = WiFiSecurityType("Open", "Unsecured", 0)
val wpa3Security = WiFiSecurityType("WPA3", "Secure", 5)

assertEquals(android.R.color.holo_red_dark, WiFiSecurityMapper.getSecurityColor(openSecurity))
assertEquals(android.R.color.holo_green_dark, WiFiSecurityMapper.getSecurityColor(wpa3Security))
}
}