package com.remotedisplay.player import android.Manifest import android.accessibilityservice.AccessibilityServiceInfo import android.annotation.SuppressLint import android.app.NotificationManager import android.content.ComponentName import android.content.Context import android.content.Intent import android.content.pm.PackageManager import android.net.Uri import android.os.Build import android.os.PowerManager import android.os.Bundle import android.provider.Settings import android.view.View import android.view.WindowManager import android.view.accessibility.AccessibilityManager import android.widget.Button import android.widget.TextView import androidx.appcompat.app.AppCompatActivity import androidx.core.app.ActivityCompat import androidx.core.content.ContextCompat import com.remotedisplay.player.service.PowerAccessibilityService class SetupActivity : AppCompatActivity() { private lateinit var accessibilityStatus: TextView private lateinit var installStatus: TextView private lateinit var notificationStatus: TextView private lateinit var enableAccessibilityBtn: Button private lateinit var enableInstallBtn: Button private lateinit var fullscreenStatus: TextView private lateinit var enableFullscreenBtn: Button private lateinit var batteryStatus: TextView private lateinit var enableBatteryBtn: Button private lateinit var overlayStatus: TextView private lateinit var enableOverlayBtn: Button private lateinit var writeSettingsStatus: TextView private lateinit var enableWriteSettingsBtn: Button private lateinit var continueBtn: Button /** * Opened from the in-service Settings menu to REVIEW permissions, not as first-run setup. * * The difference matters: proceedToNext() always goes to ProvisioningActivity, so without this * a paired, playing screen would be sent to the pairing page by the button it was told to press. * In manage mode the screen simply returns to the player. */ private val manageOnly: Boolean get() = intent?.getBooleanExtra(EXTRA_MANAGE_ONLY, false) == true companion object { const val EXTRA_MANAGE_ONLY = "EXTRA_MANAGE_ONLY" } @SuppressLint("BatteryLife") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // Skip setup if already completed — but NOT when we were opened deliberately to review // permissions from the in-service Settings menu. That is the whole point of manage mode: // every device that can reach it has setup_complete set, so without this exemption the // screen closes before it draws and the menu entry appears to do nothing. val prefs = getSharedPreferences("remote_display", MODE_PRIVATE) if (!manageOnly && prefs.getBoolean("setup_complete", false)) { proceedToNext() return } // #device-owner: a device owner self-configures the kiosk essentials (HOME launcher, kiosk // lock-task, notifications) with no user taps, and silent-install makes "unknown sources" // moot — so skip the entire manual first-run wizard. Accessibility stays optional (it can't // be auto-enabled). Guarded on ownership, so a NORMAL install still gets the full wizard. val ownerPolicy = com.remotedisplay.player.admin.STPolicy(this) if (!manageOnly && ownerPolicy.isDeviceOwner()) { ownerPolicy.applyOnboardingPolicy() prefs.edit().putBoolean("setup_complete", true).apply() // Remote control needs the accessibility service, and it's the one thing no policy can // enable — so on an MDM deploy, route the installer through the guided enable screen when // it's still off (it auto-advances once on). Already on -> straight to pairing. if (isAccessibilityEnabled()) { proceedToNext() } else { startActivity(Intent(this, OwnerAccessibilityActivity::class.java)) finish() } return } setContentView(R.layout.activity_setup) // App's UI is up — clear the boot "Starting display…" notification. getSystemService(NotificationManager::class.java)?.cancel(999) @Suppress("DEPRECATION") window.decorView.systemUiVisibility = ( View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY or View.SYSTEM_UI_FLAG_FULLSCREEN or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN ) window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) accessibilityStatus = findViewById(R.id.accessibilityStatus) installStatus = findViewById(R.id.installStatus) notificationStatus = findViewById(R.id.notificationStatus) enableAccessibilityBtn = findViewById(R.id.enableAccessibilityBtn) enableInstallBtn = findViewById(R.id.enableInstallBtn) continueBtn = findViewById(R.id.continueBtn) // Show notification row on Android 13+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { findViewById(R.id.notificationRow).visibility = View.VISIBLE findViewById