diff --git a/base/src/main/kotlin/de/staropensource/engine/base/utility/Environment.kt b/base/src/main/kotlin/de/staropensource/engine/base/utility/Environment.kt index b278258..d718869 100644 --- a/base/src/main/kotlin/de/staropensource/engine/base/utility/Environment.kt +++ b/base/src/main/kotlin/de/staropensource/engine/base/utility/Environment.kt @@ -25,6 +25,7 @@ import de.staropensource.engine.base.utility.Environment.OperatingSystem.* import kotlinx.datetime.Instant import oshi.PlatformEnum import oshi.SystemInfo +import oshi.hardware.HardwareAbstractionLayer /** * Provides information about the @@ -32,6 +33,7 @@ import oshi.SystemInfo * * @since v1-alpha10 */ +@Suppress("unused") class Environment private constructor() { /** * Companion class of [Environment]. @@ -39,43 +41,28 @@ class Environment private constructor() { * @since v1-alpha10 */ companion object { - // -----> Properties + // -----> Internal properties /** - * The operating system family - * this program is running under. + * Contains the [oshi.software.os.OperatingSystem] + * implementation used for accessing + * information about the operating + * system the engine is running on. * + * @return [oshi.software.os.OperatingSystem] instance * @since v1-alpha10 */ - var operatingSystem: OperatingSystem = UNKNOWN - private set + private var os: oshi.software.os.OperatingSystem? = null /** - * Returns the maximum amount of bits this operating system supports. - * - * This might be 32, 64 or even higher. + * Contains the [HardwareAbstractionLayer] + * implementation used for accessing + * hardware information of the system the + * engine is running on. * + * @return [HardwareAbstractionLayer] instance * @since v1-alpha10 */ - var bitAmount: Int = 0 - private set - - /** - * The point in time where the - * operating system was started at. - * - * @since v1-alpha10 - */ - var startTime: Instant = Instant.fromEpochMilliseconds(0) - private set - - /** - * Contains if this process is elevated ie. - * has superuser/administrator permissions. - * - * @since v1-alpha10 - */ - var elevated: Boolean = false - private set + private var hw: HardwareAbstractionLayer? = null // -----> Update methods @@ -86,10 +73,8 @@ class Environment private constructor() { */ @JvmStatic internal fun unset() { - operatingSystem = UNKNOWN - bitAmount = 0 - startTime = Instant.fromEpochMilliseconds(0) - elevated = false + os = null + hw = null } /** @@ -100,27 +85,281 @@ class Environment private constructor() { @JvmStatic internal fun detect() { val si: SystemInfo = SystemInfo() - val os: oshi.software.os.OperatingSystem = si.operatingSystem - - logger.diag("Running environment detection") - - // Detect operating system - when (SystemInfo.getCurrentPlatform()) { - PlatformEnum.LINUX, PlatformEnum.GNU, PlatformEnum.KFREEBSD -> operatingSystem = LINUX - PlatformEnum.FREEBSD -> operatingSystem = FREEBSD - PlatformEnum.NETBSD -> operatingSystem = NETBSD - PlatformEnum.OPENBSD -> operatingSystem = OPENBSD - //PlatformEnum.ANDROID -> Environment.operatingSystem = Environment.OperatingSystem.ANDROID // android is not yet supported by the engine, have to figure that one out sometime - PlatformEnum.WINDOWS, PlatformEnum.WINDOWSCE -> operatingSystem = WINDOWS - PlatformEnum.MACOS -> operatingSystem = MACOS - else -> logger.crash("Unsupported operating system '" + os.family + "'") - } - - // Detect other metadata - bitAmount = os.bitness - startTime = Instant.fromEpochSeconds(epochSeconds = os.systemBootTime) - elevated = os.isElevated + os = si.operatingSystem + hw = si.hardware } + + + // -----> Getters + // -------> General + /** + * Returns the amount of + * bits this platform targets. + * + * This may be 32, 64 or an + * even higher value. + * + * @return maximum of supported bits + * @since v1-alpha10 + */ + fun getOperatingSystem(): OperatingSystem? { + when (SystemInfo.getCurrentPlatform()) { + PlatformEnum.LINUX, PlatformEnum.GNU, PlatformEnum.KFREEBSD -> return LINUX + PlatformEnum.FREEBSD -> return FREEBSD + PlatformEnum.NETBSD -> return NETBSD + PlatformEnum.OPENBSD -> return OPENBSD + //PlatformEnum.ANDROID -> Environment.getOperatingSystem() = Environment.OperatingSystem.ANDROID // android is not yet supported by the engine, have to figure that one out sometime + PlatformEnum.WINDOWS, PlatformEnum.WINDOWSCE -> return WINDOWS + PlatformEnum.MACOS -> return MACOS + else -> { + logger.crash("Unsupported operating system '" + SystemInfo.getCurrentPlatform().name + "' reported by OSHI") + return null + } + } + } + + /** + * Returns the point in time where + * the system the engine is + * running on has started. + * + * @return time of system startup + * @since v1-alpha10 + */ + fun getTimeOfStartup(): Instant? { + if (os == null) + return null + + return Instant.fromEpochSeconds(epochSeconds = os!!.systemBootTime) + } + + /** + * Returns whether the current process + * is elevated and is able to execute + * superuser/administrator actions. + * + * @return elevated? + * @since v1-alpha10 + */ + fun isElevated(): Boolean? = os?.isElevated + + /** + * Returns the amount of bits + * this platform targets. + * + * This may be 32, 64 or an + * even higher value. + * + * @return maximum of supported bits + * @since v1-alpha10 + */ + fun getBitness(): Int? = os?.bitness + + // -------> Computer + /** + * Returns the name of the + * manufacturer of this computer. + * + * @return computer manufacturer name + * @since v1-alpha10 + */ + fun getComputerManufacturer(): String? = hw?.computerSystem?.manufacturer + + /** + * Returns the name of the + * model of this computer. + * + * @return computer model name + * @since v1-alpha10 + */ + fun getComputerModel(): String? = hw?.computerSystem?.model + + // -------> Firmware (BIOS, UEFI, etc.) + /** + * Returns the name of the firmware (BIOS, + * UEFI, etc.) installed on this computer. + * + * @return firmware name + * @since v1-alpha10 + */ + fun getFirmwareName(): String? = hw?.computerSystem?.firmware?.name + + /** + * Returns the description of the firmware (BIOS, + * UEFI, etc.) installed on this computer. + * + * @return firmware description + * @since v1-alpha10 + */ + fun getFirmwareDescription(): String? = hw?.computerSystem?.firmware?.description + + /** + * Returns the name of the manufacturer of this + * computer's firmware (BIOS, UEFI, etc.). + * + * @return firmware manufacturer name + * @since v1-alpha10 + */ + fun getFirmwareManufacturer(): String? = hw?.computerSystem?.firmware?.manufacturer + + /** + * Returns the version of the firmware (BIOS, + * UEFI, etc.) installed on this computer. + * + * @return firmware version + * @since v1-alpha10 + */ + fun getFirmwareVersion(): String? = hw?.computerSystem?.firmware?.version + + /** + * Returns the release date of the firmware (BIOS, + * UEFI, etc.) installed on this computer. + * + * @return firmware release date + * @since v1-alpha10 + */ + fun getFirmwareReleaseDate(): String? = hw?.computerSystem?.firmware?.releaseDate + + // -------> Motherboard + /** + * Returns the name of the model of + * this computer's motherboard. + * + * @return motherboard model name + * @since v1-alpha10 + */ + fun getMotherboardModel(): String? = hw?.computerSystem?.baseboard?.model + + /** + * Returns the version of this + * computer's motherboard. + * + * @return motherboard version + * @since v1-alpha10 + */ + fun getMotherboardVersion(): String? = hw?.computerSystem?.baseboard?.version + + /** + * Returns the serial number of + * this computer's motherboard. + * + * @return motherboard serial number + * @since v1-alpha10 + */ + fun getMotherboardSerialNumber(): String? = hw?.computerSystem?.baseboard?.serialNumber + + /** + * Returns the name of the manufacturer + * of this computer's motherboard. + * + * @return motherboard manufacturer name + * @since v1-alpha10 + */ + fun getMotherboardManufacturer(): String? = hw?.computerSystem?.baseboard?.manufacturer + + // -------> Memory + /** + * Returns the total amount of physical + * memory this system has in bytes. + * + * @return amount of physical memory in bytes + * @since v1-alpha10 + */ + fun getMemoryTotal(): Long? = hw?.memory?.total + + /** + * Returns the amount of available + * physical memory in bytes. + * + * @return amount of physical memory in bytes + * @since v1-alpha10 + */ + fun getMemoryAvailable(): Long? = hw?.memory?.available + + /** + * Returns the amount of available + * physical memory in bytes. + * + * @return amount of physical memory in bytes + * @since v1-alpha10 + */ + fun getMemoryUsed(): Long? = hw?.memory?.total?.minus(hw!!.memory!!.available) + + /** + * Returns the size of a + * memory page in bytes. + * + * @return size of a memory page in bytes + * @since v1-alpha10 + */ + fun getMemoryPageSize(): Long? = hw?.memory?.pageSize + + // -------> CPU + /** + * Returns the maximum clock speed of + * the logical processors of the CPU + * installed in this computer in Hz. + * + * @return maximum clock speed of logical processors in Hz or `-1` if it couldn't be determined + * @since v1-alpha10 + */ + fun getCPUMaxFrequency(): Long? = hw?.processor?.maxFreq + + /** + * Returns the estimated current clock + * speed of the logical processors of the + * CPU installed in this computer in Hz. + * + * Each item in the returned array + * stands for one logical processor. + * + * Depending on the platform the engine + * runs on, this may or may not be + * implemented. The algorithm used for + * calculating this estimate depends on + * the platform targeted. Some special + * restrictions apply to certain platforms. + * In short: Do not rely on the values + * in the array returned by this method. + * + * @return current clock rate of logical processors in Hz or an empty array + * @since v1-alpha10 + */ + fun getCPUCurrentFrequency(): LongArray? = hw?.processor?.currentFreq + + /** + * Returns the current amount of + * logical processors of the CPU + * installed in this computer. + * + * This value may change over time + * on some platforms. Be sure to + * query this number frequently to + * avoid out of date information. + * + * @return amount of logical processors + * @since v1-alpha10 + */ + fun getCPULogicalCount(): Int? = hw?.processor?.logicalProcessorCount + + /** + * Returns the amount of physical + * processors installed in this computer. + * + * @return amount of physical processors + * @since v1-alpha10 + */ + fun getCPUPhysicalCount(): Int? = hw?.processor?.physicalProcessorCount + + // -------> CPU + /** + * Returns an array of graphics cards + * installed in this computer. + * + * @return array of [GraphicsCard] instances + * @since v1-alpha10 + */ + fun getGPUs(): Array? = hw?.graphicsCards?.map { graphicsCard -> GraphicsCard(graphicsCard) }?.toTypedArray() } // -----> Data types @@ -131,18 +370,6 @@ class Environment private constructor() { * @since v1-alpha10 */ enum class OperatingSystem { - /** - * The operating system could not be determined. - * - * Ideally, this value should be impossible to get - * as the engine crashes during the bootstrapping - * phase if the operating system is not supported - * by the engine. - * - * @since v1-alpha10 - */ - UNKNOWN, - /** * Identifies that the application is running * under the [Linux](https://kernel.org) kernel @@ -206,4 +433,55 @@ class Environment private constructor() { */ MACOS, } + + /** + * Represents a graphics card. + * + * @since v1-alpha10 + */ + class GraphicsCard internal constructor(val graphicsCard: oshi.hardware.GraphicsCard) { + /** + * Returns the name of this graphics card. + * + * @return name + * @since v1-alpha10 + */ + fun getName(): String = graphicsCard.name + + /** + * Returns the device identifier + * of this graphics card. + * + * @return device identifier + * @since v1-alpha10 + */ + fun getDeviceIdentifier(): String = graphicsCard.deviceId + + /** + * Returns the name of the manufacturer + * of this graphics card. + * + * @return manufacturer name + * @since v1-alpha10 + */ + fun getManufacturer(): String = graphicsCard.vendor + + /** + * Returns the version of + * this graphics card. + * + * @return version + * @since v1-alpha10 + */ + fun getVersion(): String = graphicsCard.versionInfo + + /** + * Returns the amount of VRAM provided + * by this graphics card in bytes. + * + * @return amount of total VRAM + * @since v1-alpha10 + */ + fun getVideoMemory(): Long = graphicsCard.vRam + } } diff --git a/base/src/main/kotlin/de/staropensource/engine/base/utility/FileAccess.kt b/base/src/main/kotlin/de/staropensource/engine/base/utility/FileAccess.kt index 53711fc..15ac2f8 100644 --- a/base/src/main/kotlin/de/staropensource/engine/base/utility/FileAccess.kt +++ b/base/src/main/kotlin/de/staropensource/engine/base/utility/FileAccess.kt @@ -152,14 +152,14 @@ class FileAccess { .createDirectory() .verifyIsDirectory() - configDirectory = FileAccess(when (Environment.operatingSystem) { + configDirectory = FileAccess(when (Environment.getOperatingSystem()) { LINUX, FREEBSD, NETBSD, OPENBSD -> "${homeDirectory}/.config" WINDOWS -> "${homeDirectory}/AppData/Roaming/sosengine/config" MACOS -> "${homeDirectory}/Library/Application Support/sosengine/config" else -> "${homeDirectory}/.sosengine/config" }).createDirectory().verifyIsDirectory() - dataDirectory = FileAccess(when (Environment.operatingSystem) { + dataDirectory = FileAccess(when (Environment.getOperatingSystem()) { LINUX, FREEBSD, NETBSD, OPENBSD -> "${homeDirectory}/.local/share" WINDOWS -> "${homeDirectory}/AppData/Roaming/sosengine/data" MACOS -> "${homeDirectory}/Library/Application Support/sosengine/data" @@ -174,7 +174,7 @@ class FileAccess { + ProcessHandle.current().pid() ).createDirectory().verifyIsDirectory().deleteOnShutdown() - persistentCacheDirectory = FileAccess(when (Environment.operatingSystem) { + persistentCacheDirectory = FileAccess(when (Environment.getOperatingSystem()) { LINUX, FREEBSD, NETBSD, OPENBSD -> "${homeDirectory}/.cache" WINDOWS -> "${homeDirectory}/AppData/Local/Temp" MACOS -> "${homeDirectory}/Library/Caches" @@ -549,7 +549,7 @@ class FileAccess { * @since v1-alpha10 */ fun getFilesystemRestrictedNames(): String { - return when (Environment.operatingSystem) { + return when (Environment.getOperatingSystem()) { WINDOWS -> "(?i)\\|/|:|[*]|[?]|\"|<|>|[|]|CON|PRN|AUX|NUL|COM[0-9]|LPT[0-9]" else -> "/" } diff --git a/base/src/test/kotlin/de/staropensource/engine/base/utility/FileAccessTest.kt b/base/src/test/kotlin/de/staropensource/engine/base/utility/FileAccessTest.kt index ec56b66..c00ef28 100644 --- a/base/src/test/kotlin/de/staropensource/engine/base/utility/FileAccessTest.kt +++ b/base/src/test/kotlin/de/staropensource/engine/base/utility/FileAccessTest.kt @@ -62,7 +62,7 @@ class FileAccessTest : TestBase() { .replace("%", File.separator) // Apply operating system-specific updates - when (Environment.operatingSystem) { + when (Environment.getOperatingSystem()) { Environment.OperatingSystem.WINDOWS -> { if (string.startsWith(File.separator) || string.startsWith("/")) string = "C:${string}"