blob: d13ce814254ea9338972714a9618becb2715f4ea [file] [log] [blame]
// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.ui.base;
import android.content.Context;
import androidx.annotation.UiThread;
import androidx.annotation.VisibleForTesting;
import org.jni_zero.CalledByNative;
import org.chromium.base.ContextUtils;
import org.chromium.base.ThreadUtils;
import org.chromium.ui.R;
import org.chromium.ui.display.DisplayAndroid;
import org.chromium.ui.display.DisplayUtil;
/** UI utilities for accessing form factor information. */
public class DeviceFormFactor {
/**
* Minimum screen size in dp to be considered a tablet. Matches the value
* used by res/ directories. E.g.: res/values-sw600dp/values.xml
*/
public static final int MINIMUM_TABLET_WIDTH_DP = 600;
/** Matches the value set in res/values-sw600dp/values.xml */
@VisibleForTesting public static final int SCREEN_BUCKET_TABLET = 2;
/** Matches the value set in res/values-sw720dp/values.xml */
private static final int SCREEN_BUCKET_LARGET_TABLET = 3;
/**
* Each activity could be on a different display, and this will just tell you whether the
* display associated with the application context is "tablet sized".
* Use {@link #isNonMultiDisplayContextOnTablet} or {@link #isWindowOnTablet} instead.
*/
@CalledByNative
@Deprecated
public static boolean isTablet() {
return detectScreenWidthBucket(ContextUtils.getApplicationContext())
>= SCREEN_BUCKET_TABLET;
}
/**
* See {@link DisplayAndroid#getNonMultiDisplay}} for what "NonMultiDisplay" means.
* When possible, it is generally more correct to use {@link #isWindowOnTablet}.
* Only Activity instances and Contexts that wrap Activities are meaningfully associated with
* displays, so care should be taken to pass a context that makes sense.
*
* @return Whether the display associated with the given context is large enough to be
* considered a tablet and will thus load tablet-specific resources (those in the config
* -sw600).
* Not affected by Android N multi-window, but can change for external displays.
* E.g. http://developer.samsung.com/samsung-dex/testing
*/
public static boolean isNonMultiDisplayContextOnTablet(Context context) {
return detectScreenWidthBucket(context) >= SCREEN_BUCKET_TABLET;
}
/**
* @return Whether the display associated with the window is large enough to be
* considered a tablet and will thus load tablet-specific resources (those in the config
* -sw600).
* Not affected by Android N multi-window, but can change for external displays.
* E.g. http://developer.samsung.com/samsung-dex/testing
*/
@UiThread
public static boolean isWindowOnTablet(WindowAndroid windowAndroid) {
return detectScreenWidthBucket(windowAndroid) >= SCREEN_BUCKET_TABLET;
}
/**
* @return Whether the display associated with the given context is large enough to be
* considered a large tablet and will thus load large-tablet-specific resources (those
* in the config -sw720).
* Not affected by Android N multi-window, but can change for external displays.
* E.g. http://developer.samsung.com/samsung-dex/testing
*/
public static boolean isNonMultiDisplayContextOnLargeTablet(Context context) {
return detectScreenWidthBucket(context) == SCREEN_BUCKET_LARGET_TABLET;
}
/**
* Detect the screen width bucket by loading the min_screen_width_bucket value (Android will
* select the value from the correct directory; values, *-sw600dp, *-sw720dp). We can't use any
* shortcuts here since there are several devices that are phone or tablet, but load each
* others' resources (see https://crbug.com/850096 and https://crbug.com/669974 for more info).
* @param context An Android context to read resources from.
* @return The screen width bucket the device is in (see constants at the top of this class).
*/
private static int detectScreenWidthBucket(Context context) {
return context.getResources().getInteger(R.integer.min_screen_width_bucket);
}
private static int detectScreenWidthBucket(WindowAndroid windowAndroid) {
ThreadUtils.assertOnUiThread();
Context context = windowAndroid.getContext().get();
if (context == null) return 0;
return context.getResources().getInteger(R.integer.min_screen_width_bucket);
}
/**
* @return The minimum width in px at which the display should be treated like a tablet for
* layout.
*/
@UiThread
public static int getNonMultiDisplayMinimumTabletWidthPx(Context context) {
return getMinimumTabletWidthPx(DisplayAndroid.getNonMultiDisplay(context));
}
/**
* @return The minimum width in px at which the display should be treated like a tablet for
* layout.
*/
public static int getMinimumTabletWidthPx(DisplayAndroid display) {
return DisplayUtil.dpToPx(display, DeviceFormFactor.MINIMUM_TABLET_WIDTH_DP);
}
}