diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4f072fa --- /dev/null +++ b/.gitignore @@ -0,0 +1,41 @@ +# Android Studio +*.iml +.gradle/ +build/ +local.properties +.idea/ + +# Gradle files +*.gradle +gradle/ + +# Java/Kotlin class files +*.class + +# Generated files +bin/ +gen/ +out/ + +# Logs +*.log + +# Android specific +captures/ +.externalNativeBuild +.cxx + +# Virtual machine crash logs +hs_err_pid* + +# macOS +.DS_Store + +# VS Code +.vscode/ + +# Dependencies +node_modules/ + +# Environment files +.env \ No newline at end of file diff --git a/REPOSITORY_STATUS.md b/REPOSITORY_STATUS.md new file mode 100644 index 0000000..e86e3be --- /dev/null +++ b/REPOSITORY_STATUS.md @@ -0,0 +1,23 @@ +# Repository Status Report + +## Current Issues +- Inconsistent file structure +- Missing test files +- Potential file system or repository synchronization problem + +## Observed Discrepancies +- Previously listed Android project files are no longer present +- Test directory structure is incomplete +- Unable to run tests due to missing components + +## Recommended Actions +1. Verify source of truth for project files +2. Restore missing project files from backup or original source +3. Validate file integrity and repository state +4. Re-establish complete project structure +5. Set up proper test environment + +## Next Steps +- Conduct a comprehensive repository audit +- Recover or recreate missing project files +- Establish robust version control and backup processes \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 0000000..3880c46 --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,52 @@ +plugins { + id("com.android.application") + kotlin("android") +} + +dependencies { + // Kotlin standard library + implementation("org.jetbrains.kotlin:kotlin-stdlib:1.8.20") + + // Android core libraries + implementation("androidx.core:core-ktx:1.10.0") + implementation("androidx.appcompat:appcompat:1.6.1") + implementation("com.google.android.material:material:1.9.0") + + // Testing dependencies + testImplementation("junit:junit:4.13.2") + testImplementation("org.mockito:mockito-core:4.5.1") + testImplementation("org.robolectric:robolectric:4.10.3") + testImplementation("androidx.test:core:1.5.0") + testImplementation("androidx.test.ext:junit:1.1.5") +} + +android { + namespace = "com.wifiscanner" + compileSdk = 33 + + defaultConfig { + applicationId = "com.wifiscanner" + minSdk = 29 + targetSdk = 33 + versionCode = 1 + versionName = "1.0" + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + isMinifyEnabled = false + proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") + } + } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + } + + kotlinOptions { + jvmTarget = "17" + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/wifiscanner/permissions/WifiPermissionManager.kt b/src/main/kotlin/com/wifiscanner/permissions/WifiPermissionManager.kt new file mode 100644 index 0000000..f251524 --- /dev/null +++ b/src/main/kotlin/com/wifiscanner/permissions/WifiPermissionManager.kt @@ -0,0 +1,65 @@ +package com.wifiscanner.permissions + +import android.Manifest +import android.app.Activity +import android.content.Context +import android.content.pm.PackageManager +import androidx.core.app.ActivityCompat +import androidx.core.content.ContextCompat + +class WifiPermissionManager { + companion object { + // Constant for permission request code + const val WIFI_PERMISSION_REQUEST_CODE = 100 + + // Required permissions for WiFi scanning on Android 10+ + private val REQUIRED_PERMISSIONS = arrayOf( + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.ACCESS_WIFI_STATE, + Manifest.permission.CHANGE_WIFI_STATE + ) + + /** + * Checks if all required WiFi scanning permissions are granted + * @param context Context of the application + * @return Boolean indicating if all permissions are granted + */ + fun hasWifiPermissions(context: Context): Boolean { + return REQUIRED_PERMISSIONS.all { permission -> + ContextCompat.checkSelfPermission( + context, + permission + ) == PackageManager.PERMISSION_GRANTED + } + } + + /** + * Requests WiFi scanning permissions from the user + * @param activity Activity requesting the permissions + */ + fun requestWifiPermissions(activity: Activity) { + ActivityCompat.requestPermissions( + activity, + REQUIRED_PERMISSIONS, + WIFI_PERMISSION_REQUEST_CODE + ) + } + + /** + * Handles the result of permission request + * @param requestCode The request code for the permission + * @param permissions The requested permissions + * @param grantResults The grant results for the corresponding permissions + * @return Boolean indicating if all requested permissions were granted + */ + fun onRequestPermissionsResult( + requestCode: Int, + permissions: Array, + grantResults: IntArray + ): Boolean { + return requestCode == WIFI_PERMISSION_REQUEST_CODE && + grantResults.isNotEmpty() && + grantResults.all { it == PackageManager.PERMISSION_GRANTED } + } + } +} \ No newline at end of file diff --git a/src/test/kotlin/com/wifiscanner/permissions/WifiPermissionManagerTest.kt b/src/test/kotlin/com/wifiscanner/permissions/WifiPermissionManagerTest.kt new file mode 100644 index 0000000..cc79da9 --- /dev/null +++ b/src/test/kotlin/com/wifiscanner/permissions/WifiPermissionManagerTest.kt @@ -0,0 +1,77 @@ +package com.wifiscanner.permissions + +import android.Manifest +import android.content.Context +import android.content.pm.PackageManager +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import org.junit.Assert.* +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mockito.* +import org.robolectric.annotation.Config + +@RunWith(AndroidJUnit4::class) +@Config(sdk = [29]) // Target Android 10 +class WifiPermissionManagerTest { + private lateinit var context: Context + + @Before + fun setup() { + context = ApplicationProvider.getApplicationContext() + } + + @Test + fun `hasWifiPermissions returns false when permissions not granted`() { + // Mock context to simulate no permissions + val mockContext = mock(Context::class.java) + `when`(mockContext.checkPermission( + eq(Manifest.permission.ACCESS_FINE_LOCATION), + anyInt(), + anyInt() + )).thenReturn(PackageManager.PERMISSION_DENIED) + + assertFalse(WifiPermissionManager.hasWifiPermissions(mockContext)) + } + + @Test + fun `onRequestPermissionsResult returns true when all permissions granted`() { + val permissions = arrayOf( + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.ACCESS_WIFI_STATE + ) + val grantResults = intArrayOf( + PackageManager.PERMISSION_GRANTED, + PackageManager.PERMISSION_GRANTED + ) + + assertTrue( + WifiPermissionManager.onRequestPermissionsResult( + WifiPermissionManager.WIFI_PERMISSION_REQUEST_CODE, + permissions, + grantResults + ) + ) + } + + @Test + fun `onRequestPermissionsResult returns false when any permission denied`() { + val permissions = arrayOf( + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.ACCESS_WIFI_STATE + ) + val grantResults = intArrayOf( + PackageManager.PERMISSION_GRANTED, + PackageManager.PERMISSION_DENIED + ) + + assertFalse( + WifiPermissionManager.onRequestPermissionsResult( + WifiPermissionManager.WIFI_PERMISSION_REQUEST_CODE, + permissions, + grantResults + ) + ) + } +} \ No newline at end of file