/* 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 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 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 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) } } }