import android.app.Service
import android.content.Intent
import android.graphics.Color
import android.graphics.PixelFormat
import android.os.Handler
import android.os.IBinder
import android.util.Log
import android.view.Choreographer
import android.view.LayoutInflater
import android.view.View
import android.view.WindowManager
import android.widget.ImageButton
import android.widget.TextView
class FPS : Service(), Choreographer.FrameCallback {
private var windowManager: WindowManager? = null
private var fpsTextView: TextView? = null
private var popupView: View? = null
private var frameCount = 0
private var startTime: Long = 0
private val handler = Handler()
private val choreographer: Choreographer by lazy { Choreographer.getInstance() }
private var color: Int = 0
override fun onBind(intent: Intent): IBinder? {
return null
}
override fun onCreate() {
super.onCreate()
val params = WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
} else {
WindowManager.LayoutParams.TYPE_PHONE
},
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT
)
params.gravity = android.view.Gravity.TOP or android.view.Gravity.END
windowManager = getSystemService(WINDOW_SERVICE) as WindowManager
val inflater = getSystemService(LAYOUT_INFLATER_SERVICE) as LayoutInflater
popupView = inflater.inflate(R.layout.window, null)
fpsTextView = popupView?.findViewById(R.id.fps)
val closeButton: ImageButton? = popupView?.findViewById(R.id.close_button)
closeButton?.setOnClickListener {
stopSelf()
}
windowManager?.addView(popupView, params)
choreographer.postFrameCallback(this)
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
intent?.let {
color = intent.getIntExtra("color", Color.WHITE)
}
return super.onStartCommand(intent, flags, startId)
}
override fun onDestroy() {
super.onDestroy()
handler.removeCallbacksAndMessages(null)
windowManager?.removeView(popupView)
}
override fun doFrame(frameTimeNanos: Long) {
val currentTime = System.currentTimeMillis()
frameCount++
choreographer.postFrameCallback(this)
if (currentTime - startTime >= 1000) {
val fps = frameCount.toFloat() / ((currentTime - startTime) / 1000f)
val roundedFps = Math.round(fps).toInt()
Log.d("FPS", "FPS: $roundedFps")
fpsTextView?.setTextColor(color)
fpsTextView?.text = "FPS: $roundedFps"
frameCount = 0
startTime = currentTime
}
}
}
fpsTextView = popupView?.findViewById(R.id.fps)