package com.parentalmonitor.child.services import android.accessibilityservice.AccessibilityService import android.accessibilityservice.AccessibilityServiceInfo import android.graphics.Bitmap import android.os.Build import android.util.Log import android.view.Display import android.view.accessibility.AccessibilityEvent import java.io.File import java.io.FileOutputStream import java.util.concurrent.Executor class AppAccessibilityService : AccessibilityService() { companion object { const val TAG = "AppAccessibilityService" var currentPackage: String? = null var isServiceActive = false var instance: AppAccessibilityService? = null } override fun onServiceConnected() { super.onServiceConnected() isServiceActive = true instance = this val info = AccessibilityServiceInfo().apply { eventTypes = AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED or AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC flags = AccessibilityServiceInfo.FLAG_REPORT_VIEW_IDS or AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS notificationTimeout = 100 } serviceInfo = info Log.d(TAG, "Accessibility service connected") } override fun onAccessibilityEvent(event: AccessibilityEvent?) { event ?: return when (event.eventType) { AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED -> { val packageName = event.packageName?.toString() if (packageName != null && packageName != currentPackage) { currentPackage = packageName Log.d(TAG, "Active app: $packageName") } } } } fun captureScreenshot(callback: (File?) -> Unit) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { try { takeScreenshot( Display.DEFAULT_DISPLAY, Executor { it.run() }, object : TakeScreenshotCallback { override fun onSuccess(screenshot: ScreenshotResult) { try { val bitmap = Bitmap.wrapHardwareBuffer( screenshot.hardwareBuffer, screenshot.colorSpace ) if (bitmap != null) { val softBitmap = bitmap.copy(Bitmap.Config.ARGB_8888, false) bitmap.recycle() screenshot.hardwareBuffer.close() val file = File(cacheDir, "screenshot_${System.currentTimeMillis()}.png") FileOutputStream(file).use { fos -> softBitmap.compress(Bitmap.CompressFormat.PNG, 90, fos) } softBitmap.recycle() callback(file) } else { screenshot.hardwareBuffer.close() Log.e(TAG, "Failed to create bitmap from screenshot") callback(null) } } catch (e: Exception) { Log.e(TAG, "Screenshot processing error", e) callback(null) } } override fun onFailure(errorCode: Int) { Log.e(TAG, "Screenshot failed with error code: $errorCode") callback(null) } } ) } catch (e: Exception) { Log.e(TAG, "takeScreenshot error", e) callback(null) } } else { Log.e(TAG, "takeScreenshot requires Android 11+") callback(null) } } override fun onInterrupt() { Log.d(TAG, "Accessibility service interrupted") } override fun onDestroy() { super.onDestroy() isServiceActive = false instance = null Log.d(TAG, "Accessibility service destroyed") } }