diff --git a/app/build.gradle b/app/build.gradle index 0bb1039..223661b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -69,4 +69,5 @@ dependencies { androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1' implementation 'androidx.preference:preference-ktx:1.2.1' implementation 'androidx.cardview:cardview:1.0.0' + implementation 'nl.dionsegijn:konfetti-xml:2.0.2' // This library holds the fabric of reality together please dont remove it at any costs >:3 } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a54dd88..6004724 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -16,13 +16,14 @@ android:theme="@style/Theme.Pulse"> + requestGeneralPermissions() + !hasGeneralPermissions(this) -> registerForGeneralPermissions.launch(REQUIRED_PERMISSIONS) !hasDrawOverlays() -> requestDrawOverlays() !hasCallRedirectionRole() -> requestCallRedirectionRole() } } private fun hasPermissions(): Boolean { - return hasGeneralPermissions() && hasDrawOverlays() && hasCallRedirectionRole() + return hasGeneralPermissions(this) && + hasDrawOverlays(this) && + hasCallRedirectionRole(this) } private fun requestDrawOverlays() { registerForDrawOverlays.launch(Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION)) } - private fun requestGeneralPermissions() { - registerForGeneralPermissions.launch(PERMISSIONS) - } - - private fun hasGeneralPermissions(): Boolean { - return !PERMISSIONS.any { checkSelfPermission(it) != PackageManager.PERMISSION_GRANTED } - } - private fun hasDrawOverlays(): Boolean { return Settings.canDrawOverlays(this) } diff --git a/app/src/main/java/partisan/weforge/xyz/pulse/Permissions.kt b/app/src/main/java/partisan/weforge/xyz/pulse/Permissions.kt new file mode 100644 index 0000000..f33ec8d --- /dev/null +++ b/app/src/main/java/partisan/weforge/xyz/pulse/Permissions.kt @@ -0,0 +1,28 @@ + +package partisan.weforge.xyz.pulse + +import android.Manifest +import android.content.Context +import android.content.pm.PackageManager +import android.provider.Settings +import android.app.role.RoleManager + +val REQUIRED_PERMISSIONS = arrayOf( + Manifest.permission.READ_CONTACTS, + Manifest.permission.CALL_PHONE, +) + +fun hasGeneralPermissions(context: Context): Boolean { + return REQUIRED_PERMISSIONS.all { + context.checkSelfPermission(it) == PackageManager.PERMISSION_GRANTED + } +} + +fun hasDrawOverlays(context: Context): Boolean { + return Settings.canDrawOverlays(context) +} + +fun hasCallRedirectionRole(context: Context): Boolean { + val roleManager = context.getSystemService(RoleManager::class.java) + return roleManager?.isRoleHeld(RoleManager.ROLE_CALL_REDIRECTION) ?: false +} diff --git a/app/src/main/java/partisan/weforge/xyz/pulse/WelcomeActivity.kt b/app/src/main/java/partisan/weforge/xyz/pulse/WelcomeActivity.kt new file mode 100644 index 0000000..c0577dc --- /dev/null +++ b/app/src/main/java/partisan/weforge/xyz/pulse/WelcomeActivity.kt @@ -0,0 +1,107 @@ +package partisan.weforge.xyz.pulse + +import android.Manifest +import android.app.role.RoleManager +import android.content.Intent +import android.content.pm.PackageManager +import android.os.Bundle +import android.provider.Settings +import android.view.View +import androidx.activity.result.contract.ActivityResultContracts +import androidx.appcompat.app.AppCompatActivity +import nl.dionsegijn.konfetti.core.Party +import nl.dionsegijn.konfetti.core.Position +import nl.dionsegijn.konfetti.core.emitter.Emitter +import nl.dionsegijn.konfetti.xml.KonfettiView +import partisan.weforge.xyz.pulse.databinding.ActivityWelcomeBinding +import java.util.concurrent.TimeUnit +import partisan.weforge.xyz.pulse.hasGeneralPermissions +import partisan.weforge.xyz.pulse.hasDrawOverlays +import partisan.weforge.xyz.pulse.hasCallRedirectionRole +import partisan.weforge.xyz.pulse.REQUIRED_PERMISSIONS + +class WelcomeActivity : AppCompatActivity() { + private lateinit var binding: ActivityWelcomeBinding + private lateinit var prefs: Preferences + private var roleManager: RoleManager? = null + + private val requestPermissionsLauncher = registerForActivityResult( + ActivityResultContracts.RequestMultiplePermissions() + ) {} + + private val requestOverlayLauncher = registerForActivityResult( + ActivityResultContracts.StartActivityForResult() + ) {} + + private val requestRoleLauncher = registerForActivityResult( + ActivityResultContracts.StartActivityForResult() + ) {} + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + if (hasGeneralPermissions(this) && hasDrawOverlays(this) && hasCallRedirectionRole(this)) { + startActivity(Intent(this, MainActivity::class.java)) + finish() + return + } + + binding = ActivityWelcomeBinding.inflate(layoutInflater) + setContentView(binding.root) + + prefs = Preferences(this) + roleManager = getSystemService(RoleManager::class.java) + + binding.activateButton.setOnClickListener { + when { + !hasGeneralPermissions(this) -> { + requestPermissionsLauncher.launch(REQUIRED_PERMISSIONS) + } + !hasDrawOverlays(this) -> { + requestOverlayLauncher.launch(Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION)) + } + !hasCallRedirectionRole(this) -> { + requestRoleLauncher.launch(roleManager?.createRequestRoleIntent(RoleManager.ROLE_CALL_REDIRECTION)) + } + else -> { + prefs.isEnabled = true + showConfettiAndContinue() + } + } + } + } + + private fun showConfettiAndContinue() { + binding.appIcon.post { + val iconLocation = IntArray(2) + binding.appIcon.getLocationOnScreen(iconLocation) + + val iconCenterX = iconLocation[0] + binding.appIcon.width / 2f + val iconCenterY = iconLocation[1] + binding.appIcon.height / 2f + + val rootWidth = binding.root.width.toFloat() + val rootHeight = binding.root.height.toFloat() + + val relativeX = (iconCenterX / rootWidth).toDouble() + val relativeY = (iconCenterY / rootHeight).toDouble() + + binding.konfettiView.visibility = View.VISIBLE + binding.konfettiView.start( + Party( + speed = 30f, + maxSpeed = 50f, + damping = 0.9f, + spread = 360, + colors = listOf(0xfce18a, 0xff726d, 0xf4306d, 0xb48def), + position = Position.Relative(relativeX, relativeY), + emitter = Emitter(duration = 2, TimeUnit.SECONDS).perSecond(100) + ) + ) + + binding.konfettiView.postDelayed({ + startActivity(Intent(this, MainActivity::class.java)) + finish() + }, 2000) + } + } +} diff --git a/app/src/main/res/layout/activity_welcome.xml b/app/src/main/res/layout/activity_welcome.xml new file mode 100644 index 0000000..77183e8 --- /dev/null +++ b/app/src/main/res/layout/activity_welcome.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + +