623 lines
21 KiB
Kotlin
623 lines
21 KiB
Kotlin
package com.ea.ironmonkey
|
|
|
|
import android.annotation.SuppressLint
|
|
import android.app.AlertDialog
|
|
import android.content.DialogInterface
|
|
import android.content.Intent
|
|
import android.content.pm.ActivityInfo
|
|
import android.hardware.SensorManager
|
|
import android.media.AudioManager
|
|
import android.opengl.GLES20
|
|
import android.os.Build
|
|
import android.os.Bundle
|
|
import android.os.PowerManager
|
|
import android.os.PowerManager.WakeLock
|
|
import android.util.DisplayMetrics
|
|
import android.util.Log
|
|
import android.view.KeyEvent
|
|
import android.view.MotionEvent
|
|
import android.view.inputmethod.InputMethodManager
|
|
import androidx.activity.ComponentActivity
|
|
import androidx.lifecycle.Lifecycle
|
|
import com.ea.EAIO.EAIO
|
|
import com.ea.EAMIO.StorageDirectory
|
|
import com.ea.easp.EASPHandler
|
|
import com.ea.games.nfs13_na.BuildConfig
|
|
//import com.ea.nimble.ApplicationLifecycle
|
|
import java.io.BufferedReader
|
|
import java.io.File
|
|
import java.io.FileReader
|
|
import java.io.IOException
|
|
import java.util.Locale
|
|
import javax.microedition.khronos.egl.EGLConfig
|
|
import javax.microedition.khronos.opengles.GL10
|
|
import kotlin.math.min
|
|
import kotlin.math.sqrt
|
|
import kotlin.system.exitProcess
|
|
|
|
|
|
//TODO при заходе в магазин - вылет
|
|
class GameActivity : ComponentActivity(), DrawFrameListener {
|
|
|
|
init {
|
|
//System.loadLibrary("nimble")
|
|
System.loadLibrary("app")
|
|
}
|
|
|
|
private var splashDelay: Long = 0
|
|
private var splashTimer: Long = 0
|
|
|
|
private lateinit var easpHandler: EASPHandler
|
|
private lateinit var gameRenderer: GameRenderer
|
|
lateinit var runLoop: RunLoop
|
|
lateinit var gameGLSurfaceView: GameGLSurfaceView
|
|
lateinit var accelerometer: Accelerometer
|
|
private lateinit var mWakeLock: WakeLock
|
|
private lateinit var mAudioManager: AudioManager
|
|
|
|
private val saveFile = "/data/data/${BuildConfig.APPLICATION_ID}/files/var/nfstr_save.sb"
|
|
private val dest = "/sdcard/Android/data/${BuildConfig.APPLICATION_ID}/files/saveTracking"
|
|
|
|
companion object {
|
|
|
|
const val STATE_RESTORE_CONTEXT = 7
|
|
const val STATE_GAME_START = 8
|
|
private var oldState = 0
|
|
|
|
@JvmField
|
|
var state = 0
|
|
|
|
//В нативном коде эти методы помечны как статические
|
|
@JvmStatic
|
|
fun GetDeviceName() = Build.MODEL
|
|
|
|
@JvmStatic
|
|
fun GetApplicationVersion() = BuildConfig.VERSION_NAME
|
|
|
|
@JvmStatic
|
|
fun GetDefaultLanguage() = Locale.getDefault().toString().substring(0, 2)
|
|
|
|
@JvmStatic
|
|
val osVersion = Build.VERSION.RELEASE
|
|
}
|
|
|
|
//Метод вызвывется из нативного кода поэтому нужно их существование
|
|
fun installWallpaper() {}
|
|
fun needInstallWallpaper() = false
|
|
fun openURL(str: String) = Log.d("OpenURL", str)
|
|
fun openURLinBrowser(str: String) = Log.d("OpenURLinBrowser", str)
|
|
fun getDisplayMetrics() = resources.displayMetrics
|
|
fun GetViewRoot() = window.decorView.getRootView().parent
|
|
fun CallGC() {
|
|
Log.d(this.localClassName, "Call garbage collector")
|
|
System.gc()
|
|
}
|
|
|
|
|
|
private fun ForceHideVirtualKeyboard() {
|
|
val currentFocus = currentFocus
|
|
if (currentFocus != null) {
|
|
(getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager).hideSoftInputFromWindow(
|
|
currentFocus.windowToken,
|
|
0
|
|
)
|
|
}
|
|
window.setSoftInputMode(3)
|
|
}
|
|
|
|
|
|
private fun wakeLockAcquire() {
|
|
val powerManager = getSystemService(POWER_SERVICE) as PowerManager
|
|
mWakeLock = powerManager.newWakeLock(10, localClassName)
|
|
if (!mWakeLock.isHeld) {
|
|
try {
|
|
mWakeLock.acquire(10*60*1000L /*10 minutes*/)
|
|
} catch (e: SecurityException) {
|
|
Log.w(this.localClassName, "Missing WAKE_LOCK permission.")
|
|
}
|
|
}
|
|
this.assets
|
|
}
|
|
|
|
private fun wakeLockRelease() {
|
|
if (mWakeLock != null && mWakeLock!!.isHeld) {
|
|
try {
|
|
mWakeLock!!.release()
|
|
} catch (e: SecurityException) {
|
|
Log.w(this.localClassName, "Missing WAKE_LOCK permission.")
|
|
}
|
|
}
|
|
}
|
|
|
|
fun IsSystemKey(key: Int) = false
|
|
|
|
fun ShowMessage(message: String, strArr: Array<String?>, finish: Boolean) {
|
|
Log.d(this.localClassName, "ShowMessage msg = $message finish = $finish")
|
|
|
|
val dialog = AlertDialog.Builder(this)
|
|
dialog.setMessage(message)
|
|
dialog.setCancelable(false)
|
|
dialog.setPositiveButton(strArr[0]) { _: DialogInterface?, _: Int ->
|
|
if (finish) {
|
|
finish()
|
|
}
|
|
}
|
|
dialog.show()
|
|
}
|
|
|
|
fun calcPerformanceScore(
|
|
cpuUsage: Float,
|
|
processorCount: Int,
|
|
screenWidth: Int,
|
|
screenHeight: Int
|
|
): Float {
|
|
// Log input parameters for debugging
|
|
Log.i(
|
|
this.localClassName,
|
|
"calculatePerformanceScore($cpuUsage, $processorCount, $screenWidth, $screenHeight)"
|
|
)
|
|
|
|
// Calculate CPU-related score
|
|
var cpuScore = 0.001f * cpuUsage * 3.0f
|
|
if (processorCount > 1) {
|
|
// If there is more than one processor, adjust the CPU score
|
|
cpuScore += 0.001f * cpuUsage * min(processorCount.toFloat(), 3f) * 0.5f
|
|
}
|
|
|
|
// Calculate screen-related score
|
|
val screenScore =
|
|
sqrt((screenWidth * screenHeight).toDouble()) * 0.001 * 0.5
|
|
|
|
// Log CPU information
|
|
try {
|
|
val cpuInfo = BufferedReader(FileReader("/proc/cpuinfo")).readLine()
|
|
Log.i(this.localClassName, "CPU Info: $cpuInfo")
|
|
} catch (e: IOException) {
|
|
e.printStackTrace()
|
|
}
|
|
|
|
// Log device model
|
|
val deviceModel = Build.MODEL
|
|
Log.i(this.localClassName, "Device Model: $deviceModel")
|
|
|
|
// Calculate the final performance score and return it
|
|
return ((1.0f + cpuScore) / (1.0f + screenScore.toFloat())) / 3
|
|
}
|
|
|
|
fun getPerformanceScore(): Float {
|
|
var cpuFrequency = 0.0f
|
|
var processorCount = 0
|
|
|
|
// Read CPU information from file
|
|
val cpuInfo = readCpuFile("present")
|
|
if (cpuInfo.isNotEmpty()) {
|
|
val cpuList = parseCpuList(cpuInfo)
|
|
|
|
// Iterate through the CPU list and get max frequency
|
|
for (cpuId: Int? in cpuList) {
|
|
val maxFreq =
|
|
readCpuFile(String.format("cpu%d/cpufreq/cpuinfo_max_freq", cpuId))
|
|
if (maxFreq.isNotEmpty()) {
|
|
try {
|
|
cpuFrequency = maxFreq.toInt().toFloat() * 0.001f
|
|
break
|
|
} catch (e: NumberFormatException) {
|
|
e.printStackTrace()
|
|
}
|
|
}
|
|
}
|
|
processorCount = cpuList.size
|
|
}
|
|
|
|
// Get screen metrics
|
|
val displayMetrics = DisplayMetrics()
|
|
windowManager.defaultDisplay.getMetrics(displayMetrics)
|
|
|
|
// Calculate the performance score and return it
|
|
return calcPerformanceScore(
|
|
cpuFrequency,
|
|
processorCount,
|
|
displayMetrics.widthPixels,
|
|
displayMetrics.heightPixels
|
|
)
|
|
}
|
|
|
|
fun getTotalMemory(): Int {
|
|
var totalMemoryInMB = 0
|
|
val memInfoFile = File("/proc/meminfo")
|
|
if (!memInfoFile.exists()) {
|
|
Log.d("mem", "Meminfo file not found")
|
|
return 0
|
|
}
|
|
try {
|
|
val reader = BufferedReader(FileReader(memInfoFile))
|
|
var line: String
|
|
while ((reader.readLine().also { line = it }) != null) {
|
|
val parts =
|
|
line.split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
|
|
if (parts.size != 2) {
|
|
continue
|
|
}
|
|
val key = parts[0].trim { it <= ' ' }.lowercase(Locale.getDefault())
|
|
val value = parts[1].trim { it <= ' ' }
|
|
if (key != "memtotal") {
|
|
continue
|
|
}
|
|
val valueParts =
|
|
value.split(" ".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
|
|
if (valueParts.isNotEmpty()) {
|
|
try {
|
|
totalMemoryInMB = valueParts[0].toInt() / 1024
|
|
} catch (e: NumberFormatException) {
|
|
e.printStackTrace()
|
|
}
|
|
}
|
|
break // We found "MemTotal," so we can exit the loop
|
|
}
|
|
reader.close()
|
|
} catch (e: Exception) {
|
|
Log.e(
|
|
this.localClassName,
|
|
"Error reading system file: ${memInfoFile.absolutePath} (${e.message})"
|
|
)
|
|
}
|
|
Log.d("mem", "Total Memory (MB): $totalMemoryInMB")
|
|
return totalMemoryInMB
|
|
}
|
|
|
|
external fun nativeOnCreate()
|
|
external fun nativeOnDestroy()
|
|
external fun nativeOnPause()
|
|
external fun nativeOnPhysicalKeyDown(i: Int, i2: Int)
|
|
external fun nativeOnPhysicalKeyUp(i: Int, i2: Int)
|
|
external fun nativeOnPhysicalKeyboardVisibilityChanged(z: Boolean)
|
|
external fun nativeOnPhysicalNavigationVisibilityChanged(z: Boolean)
|
|
external fun nativeOnRestart()
|
|
external fun nativeOnResume()
|
|
external fun nativeOnStart()
|
|
external fun nativeOnStop()
|
|
external fun nativeRestoreContext(): Boolean
|
|
external fun nativeSurfaceChanged(gl10: GL10?, i: Int, i2: Int)
|
|
external fun nativeSurfaceCreated(gl10: GL10?, eGLConfig: EGLConfig?)
|
|
|
|
public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
|
super.onActivityResult(requestCode, resultCode, data)
|
|
easpHandler!!.onActivityResult(requestCode, resultCode, data)
|
|
//ApplicationLifecycle.onActivityResult(requestCode, resultCode, data, this)
|
|
}
|
|
|
|
public override fun onCreate(bundle: Bundle?) {
|
|
|
|
super.onCreate(bundle)
|
|
|
|
MogaController.registerControllerHandlers(
|
|
context = baseContext,
|
|
onInputDeviceAdded = {
|
|
Log.i("Controller", "controller is connected!")
|
|
val event = MogaController.createConnectEvent(it)
|
|
MogaController.nativeOnStateEvent(event)
|
|
},
|
|
onInputDeviceRemoved = {
|
|
Log.i("Controller", "controller is disconnected!")
|
|
val event = MogaController.createDisconnectEvent(it)
|
|
MogaController.nativeOnStateEvent(event)
|
|
},
|
|
onInputDeviceChanged = {
|
|
Log.i("Controller", "controller is changed!")
|
|
}
|
|
)
|
|
|
|
val className = this.localClassName
|
|
val currentState = lifecycle.currentState
|
|
|
|
Log.i(className, "onCreate")
|
|
Log.i(className, "GameActivity.state = $state")
|
|
|
|
if (currentState == Lifecycle.State.DESTROYED) {
|
|
Log.w(className, "onCreate called on destroyed app, finishing")
|
|
finish()
|
|
return
|
|
}
|
|
|
|
if (currentState >= Lifecycle.State.CREATED) {
|
|
Log.w(className, "onCreate ignored, lifecycle is already $currentState")
|
|
return
|
|
}
|
|
|
|
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
|
|
requestWindowFeature(1)
|
|
Log.d("Model", Build.MODEL)
|
|
mAudioManager = getSystemService(AUDIO_SERVICE) as AudioManager
|
|
|
|
val sensorManager = getSystemService(SENSOR_SERVICE) as SensorManager
|
|
val defaultSensor = sensorManager.getDefaultSensor(1)
|
|
val rotation = window.windowManager.defaultDisplay.rotation
|
|
|
|
accelerometer = Accelerometer(sensorManager, defaultSensor, rotation)
|
|
|
|
gameGLSurfaceView = GameGLSurfaceView(this)
|
|
gameRenderer = GameRenderer(this)
|
|
gameRenderer.setDrawFrameListener(this)
|
|
gameGLSurfaceView.setRenderer(gameRenderer)
|
|
runLoop = RunLoop(gameGLSurfaceView)
|
|
|
|
val frameLayout = ComposeFrameLayout(this, gameGLSurfaceView = gameGLSurfaceView)
|
|
setContentView(frameLayout)
|
|
|
|
Log.d(className, "Init EAIO/EAMIO")
|
|
EAIO.Startup(this)
|
|
StorageDirectory.Startup()
|
|
|
|
Log.d(className, "Init EASPHandler")
|
|
easpHandler = EASPHandler(this, frameLayout, gameGLSurfaceView)
|
|
easpHandler.onCreate()
|
|
|
|
//ApplicationLifecycle.onActivityCreate(bundle, this)
|
|
Log.d(className, "nativeOnCreate")
|
|
nativeOnCreate()
|
|
|
|
}
|
|
|
|
|
|
public override fun onDestroy() {
|
|
|
|
Log.i("Debug", "onDestroy")
|
|
Log.i(this.localClassName, "onDestroy")
|
|
super.onDestroy()
|
|
easpHandler.onDestroy()
|
|
if (state == 8) {
|
|
//ApplicationLifecycle.onActivityDestroy(this)
|
|
nativeOnDestroy()
|
|
}
|
|
StorageDirectory.Shutdown()
|
|
EAIO.Shutdown()
|
|
exitProcess(0)
|
|
}
|
|
|
|
override fun dispatchGenericMotionEvent(ev: MotionEvent?): Boolean {
|
|
Log.i("GameActivity", ev.toString())
|
|
|
|
if (MogaController.deviceIsController(ev?.deviceId!!))
|
|
MogaController.onMotionEvent(MogaController.androidMotionEventToBda(ev))
|
|
|
|
return super.dispatchGenericMotionEvent(ev)
|
|
}
|
|
|
|
@SuppressLint("RestrictedApi")
|
|
override fun dispatchKeyEvent(event: KeyEvent?): Boolean {
|
|
|
|
if (MogaController.deviceIsController(event?.deviceId!!))
|
|
MogaController.onKeyEvent(MogaController.androidKeyEventToBda(event))
|
|
|
|
return super.dispatchKeyEvent(event)
|
|
}
|
|
|
|
|
|
|
|
override fun onDrawFrame(gl10: GL10) {
|
|
Log.d(this.localClassName, "onDrawFrame state=$state")
|
|
var isStarted = false
|
|
when (state) {
|
|
STATE_RESTORE_CONTEXT -> {
|
|
run {
|
|
//Log.i("state_in splash is null", (this.splash == null).toString() + "")
|
|
/*if (this.splash == null) {
|
|
this.splash = SplashScreen(this)
|
|
this.splash!!.init(
|
|
gl10,
|
|
this.gameRenderer!!.width,
|
|
this.gameRenderer!!.height
|
|
)
|
|
this.splashDelay = System.currentTimeMillis() + 2000
|
|
}*/
|
|
if (this.splashDelay < System.currentTimeMillis() /*&& hasWindowFocus()*/) {
|
|
if (oldState != 8) {
|
|
state = oldState
|
|
} else {
|
|
this.splashTimer = System.currentTimeMillis() + 300
|
|
state = 8
|
|
}
|
|
}
|
|
}
|
|
run {
|
|
if (this.splashTimer < System.currentTimeMillis() && nativeRestoreContext()) {
|
|
nativeOnStart()
|
|
nativeOnResume()
|
|
this.gameRenderer!!.setDrawFrameListener(null)
|
|
isStarted = true
|
|
}
|
|
}
|
|
}
|
|
|
|
STATE_GAME_START -> {
|
|
if (splashTimer < System.currentTimeMillis() && nativeRestoreContext()) {
|
|
nativeOnStart()
|
|
nativeOnResume()
|
|
gameRenderer.setDrawFrameListener(null)
|
|
isStarted = true
|
|
}
|
|
}
|
|
}
|
|
//GLES20.glClearColor(1.0f, 1.0f, 1.0f, 1.0f)
|
|
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT or GLES20.GL_DEPTH_BUFFER_BIT)
|
|
GLES20.glClear(16640)
|
|
/* if (splash != null) {
|
|
splash!!.draw(gl10, gameRenderer!!.width, gameRenderer!!.height)
|
|
}
|
|
if (isStarted && splash != null) {
|
|
splash!!.destroy(gl10)
|
|
splash = null
|
|
}*/
|
|
}
|
|
|
|
override fun onKeyDown(i: Int, keyEvent: KeyEvent): Boolean {
|
|
super.onKeyDown(i, keyEvent)
|
|
if (state != 8) {
|
|
return true
|
|
}
|
|
if ((i == 4 || i == 108) && keyEvent.repeatCount > 0) {
|
|
return true
|
|
}
|
|
val scanCode = keyEvent.scanCode
|
|
gameGLSurfaceView.queueEvent { nativeOnPhysicalKeyDown(i, scanCode) }
|
|
return IsSystemKey(i)
|
|
}
|
|
|
|
override fun onKeyUp(i: Int, keyEvent: KeyEvent): Boolean {
|
|
super.onKeyUp(i, keyEvent)
|
|
if (state != 8) {
|
|
return true
|
|
}
|
|
val scanCode = keyEvent.scanCode
|
|
gameGLSurfaceView.queueEvent { nativeOnPhysicalKeyUp(i, scanCode) }
|
|
return IsSystemKey(i)
|
|
}
|
|
|
|
public override fun onPause() {
|
|
super.onPause()
|
|
Log.i("Debug", "onPause")
|
|
Log.i(this.localClassName, "onPause state=$state")
|
|
mAudioManager!!.setStreamMute(3, true)
|
|
gameGLSurfaceView.onPause()
|
|
onWindowFocusChanged(false)
|
|
//ApplicationLifecycle.onActivityPause(this)
|
|
nativeOnPause()
|
|
}
|
|
|
|
public override fun onRestart() {
|
|
Log.i("Debug", "onRestart")
|
|
Log.i(this.localClassName, "onRestart")
|
|
Log.i(this.localClassName, "TouchEvent, GameActivity.state = $state")
|
|
super.onRestart()
|
|
//ApplicationLifecycle.onActivityRestart(this)
|
|
nativeOnRestart()
|
|
}
|
|
|
|
public override fun onResume() {
|
|
Log.i("Debug", "onResume")
|
|
Log.i(this.localClassName, "onResume")
|
|
Log.i("check", "GameActivity.state = $state")
|
|
super.onResume()
|
|
if (state != 7) {
|
|
oldState = state
|
|
state = 8
|
|
gameRenderer.setDrawFrameListener(this)
|
|
}
|
|
gameGLSurfaceView.onResume()
|
|
//ApplicationLifecycle.onActivityResume(this)
|
|
nativeOnResume()
|
|
MogaController.doForAllControllers {
|
|
val event = MogaController.createConnectEvent(it)
|
|
MogaController.nativeOnStateEvent(event)
|
|
}
|
|
}
|
|
|
|
public override fun onSaveInstanceState(bundle: Bundle) {
|
|
super.onSaveInstanceState(bundle)
|
|
//ApplicationLifecycle.onActivitySaveInstanceState(bundle, this)
|
|
}
|
|
|
|
public override fun onStart() {
|
|
System.gc()
|
|
Log.i("Debug", "onStart")
|
|
Log.i(this.localClassName, "onStart")
|
|
super.onStart()
|
|
Log.i(this.localClassName, "onStart 1")
|
|
wakeLockAcquire()
|
|
Log.i(this.localClassName, "onStart 2")
|
|
if (lifecycle.currentState < Lifecycle.State.STARTED || lifecycle.currentState == Lifecycle.State.DESTROYED) {
|
|
Log.i(this.localClassName, "onStart 3")
|
|
Log.i(this.localClassName, "nativeOnStart")
|
|
nativeOnStart()
|
|
Log.i(this.localClassName, "nativeOnStart - end")
|
|
Log.i(this.localClassName, "ApplicationLifecycle")
|
|
//ApplicationLifecycle.onActivityStart(this)
|
|
}
|
|
Log.w(
|
|
this.localClassName,
|
|
"onStart ignored, lifecycle is already ${lifecycle.currentState}"
|
|
)
|
|
}
|
|
|
|
public override fun onStop() {
|
|
super.onStop()
|
|
Log.i("Debug", "onStop")
|
|
Log.i(this.localClassName, "onStop")
|
|
if (lifecycle.currentState >= Lifecycle.State.RESUMED) {
|
|
Log.w(
|
|
this.localClassName,
|
|
"onStop ignored, lifecycle is already ${lifecycle.currentState}"
|
|
)
|
|
return
|
|
}
|
|
wakeLockRelease()
|
|
nativeOnStop()
|
|
mAudioManager!!.setStreamMute(3, false)
|
|
mAudioManager!!.setStreamSolo(3, false)
|
|
if (mAudioManager!!.abandonAudioFocus(null) == 0) {
|
|
Log.e(this.localClassName, "abandonAudioFocus failed")
|
|
}
|
|
}
|
|
|
|
override fun onWindowFocusChanged(hasFocus: Boolean) {
|
|
Log.i("Debug", "onWindowFocusChanged")
|
|
super.onWindowFocusChanged(hasFocus)
|
|
Log.i(this.localClassName, "onWindowsFocusChanged($hasFocus) state=$state")
|
|
if (hasFocus) {
|
|
mAudioManager!!.setStreamMute(3, false)
|
|
} else {
|
|
ForceHideVirtualKeyboard()
|
|
nativeOnPhysicalKeyDown(131, 0)
|
|
nativeOnPhysicalKeyUp(131, 0)
|
|
if (state == 8) {
|
|
mAudioManager!!.setStreamMute(3, true)
|
|
oldState = state
|
|
state = 7
|
|
gameRenderer.setDrawFrameListener(this)
|
|
}
|
|
}
|
|
//ApplicationLifecycle.onActivityWindowFocusChanged(hasFocus, this)
|
|
}
|
|
|
|
fun parseCpuList(cpuInfo: String): List<Int> {
|
|
val arrayList = mutableListOf<Int>()
|
|
val split = cpuInfo.split(",".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
|
|
for (str2: String in split) {
|
|
if (str2.contains("-")) {
|
|
val split2 = str2.split("-".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
|
|
if (split2.size >= 2) {
|
|
try {
|
|
val parseInt = split2[0].toInt()
|
|
val parseInt2 = split2[1].toInt()
|
|
for (i in parseInt..parseInt2) {
|
|
arrayList.add(i)
|
|
}
|
|
} catch (_: NumberFormatException) {
|
|
}
|
|
}
|
|
} else {
|
|
try {
|
|
arrayList.add(str2.toInt())
|
|
} catch (_: NumberFormatException) {
|
|
}
|
|
}
|
|
}
|
|
return arrayList
|
|
}
|
|
|
|
fun readCpuFile(str: String): String {
|
|
val file = File("/sys/devices/system/cpu/$str")
|
|
runCatching {
|
|
return file.readLines()[0]
|
|
}.onFailure {
|
|
Log.e(
|
|
this.localClassName,
|
|
"Error reading system file: ${file.absoluteFile} (${it.message})"
|
|
)
|
|
return ""
|
|
}
|
|
return ""
|
|
}
|
|
|
|
}
|