Source code
Revision control
Copy as Markdown
Other Tools
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
package org.mozilla.fenix.utils
import android.content.Context
import android.content.res.Resources
import android.os.Build
import android.util.DisplayMetrics
import android.util.Size
import android.view.WindowManager
import androidx.annotation.RequiresApi
import androidx.core.content.ContextCompat
import org.mozilla.fenix.ext.isLargeWindow
import kotlin.math.min
private const val LARGE_SCREEN_THRESHOLD_DP = 600
/**
* Returns true if the device has a large screen size. This is determined by the smallest width
* of the screen (not window). This value will not change over the course of the app's lifecycle.
* To determine whether the app's window size is at least that of a tablet, consider using
* [Context.isLargeWindow] instead.
*/
fun Context.isLargeScreenSize(): Boolean =
smallestScreenWidthDp() >= LARGE_SCREEN_THRESHOLD_DP
/**
* Returns the smallest width of the screen in dp.
*/
private fun Context.smallestScreenWidthDp(): Float {
val size = ScreenMetricsCompat.getScreenSize(this)
return min(size.width, size.height) / resources.displayMetrics.density
}
/**
* Compat utility to get screen metrics.
*/
private object ScreenMetricsCompat {
private val screenMetricsApi: ScreenMetricsApi =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
ScreenMetricsApiApi30Impl()
} else {
ScreenMetricsApiImpl()
}
/**
* @see [ScreenMetricsApi.getScreenSize]
*/
fun getScreenSize(context: Context): Size = screenMetricsApi.getScreenSize(context)
/**
* Interface to abstract the implementation of the screen metrics API based on the SDK version.
*/
private interface ScreenMetricsApi {
/**
* Returns screen [Size] in pixels.
*
* @param context [Context] to get the display metrics from. Use a visual Context from
* Activity or View.
*/
fun getScreenSize(context: Context): Size
}
/**
* Implementation of the screen metrics API for API 30 and above.
*/
@RequiresApi(Build.VERSION_CODES.R)
private class ScreenMetricsApiApi30Impl : ScreenMetricsApi {
/**
* @see [ScreenMetricsApi.getScreenSize]
*/
override fun getScreenSize(context: Context): Size {
val windowManager = ContextCompat.getSystemService(context, WindowManager::class.java)
if (windowManager != null) {
val windowMetrics = windowManager.maximumWindowMetrics
return Size(windowMetrics.bounds.width(), windowMetrics.bounds.height())
} else {
// Fallback to display metrics if WindowManager is not available.
val displayMetrics = Resources.getSystem().displayMetrics
return Size(displayMetrics.widthPixels, displayMetrics.heightPixels)
}
}
}
/**
* Implementation of the screen metrics API for API 29 and below.
*/
private class ScreenMetricsApiImpl : ScreenMetricsApi {
/**
* @see [ScreenMetricsApi.getScreenSize]
*/
@Suppress("DEPRECATION")
override fun getScreenSize(context: Context): Size {
val display =
ContextCompat.getSystemService(context, WindowManager::class.java)?.defaultDisplay
val metrics: DisplayMetrics = if (display != null) {
DisplayMetrics().also {
display.getRealMetrics(it)
}
} else {
Resources.getSystem().displayMetrics
}
return Size(metrics.widthPixels, metrics.heightPixels)
}
}
}