Add method to compute a WindowSizeClass from WindowMetrics

Add a utility method to create a WindowSizeClass from WindowMetrics.
Update WindowMetrics equals/hashCode/toString to include all properties.

Relnote: "Add a utility method to get a WindowSizeClass from
WindowMetrics."

Bug: 364908578
Test: ./gradlew window:window:test
Change-Id: I83f1fb0faa8c28c212dec7b6f1628c0fa4a7e736
diff --git a/window/window/api/current.txt b/window/window/api/current.txt
index 9931de5..b4bf8af 100644
--- a/window/window/api/current.txt
+++ b/window/window/api/current.txt
@@ -623,3 +623,11 @@
 
 }
 
+package androidx.window.layout.adapter {
+
+  public final class WindowSizeClassFactory {
+    method public static androidx.window.core.layout.WindowSizeClass computeWindowSizeClass(java.util.Set, androidx.window.layout.WindowMetrics windowMetrics);
+  }
+
+}
+
diff --git a/window/window/api/restricted_current.txt b/window/window/api/restricted_current.txt
index 6f55013..2708556 100644
--- a/window/window/api/restricted_current.txt
+++ b/window/window/api/restricted_current.txt
@@ -739,3 +739,11 @@
 
 }
 
+package androidx.window.layout.adapter {
+
+  public final class WindowSizeClassFactory {
+    method public static androidx.window.core.layout.WindowSizeClass computeWindowSizeClass(java.util.Set, androidx.window.layout.WindowMetrics windowMetrics);
+  }
+
+}
+
diff --git a/window/window/build.gradle b/window/window/build.gradle
index 10c45a2..1bf8a23 100644
--- a/window/window/build.gradle
+++ b/window/window/build.gradle
@@ -52,6 +52,7 @@
     implementation("androidx.annotation:annotation:1.8.1")
     implementation("androidx.collection:collection:1.4.2")
     implementation("androidx.core:core:1.8.0")
+    implementation(project(":window:window-core"))
 
     def extensions_core_version = "androidx.window.extensions.core:core:1.0.0"
     def extensions_version = "androidx.window.extensions:extensions:1.4.0-beta01"
diff --git a/window/window/src/main/java/androidx/window/layout/WindowMetrics.kt b/window/window/src/main/java/androidx/window/layout/WindowMetrics.kt
index 6707353..c1bf62a 100644
--- a/window/window/src/main/java/androidx/window/layout/WindowMetrics.kt
+++ b/window/window/src/main/java/androidx/window/layout/WindowMetrics.kt
@@ -36,7 +36,6 @@
 internal constructor(
     private val _bounds: Bounds,
     private val _windowInsetsCompat: WindowInsetsCompat,
-
     /**
      * Returns the logical density of the display this window is in.
      *
@@ -65,8 +64,14 @@
     val bounds: Rect
         get() = _bounds.toRect()
 
-    override fun toString(): String {
-        return "WindowMetrics( bounds=$_bounds, windowInsetsCompat=$_windowInsetsCompat)"
+    /**
+     * Returns the [WindowInsetsCompat] of the area associated with this window or visual context.
+     */
+    @ExperimentalWindowApi
+    @RequiresApi(VERSION_CODES.R)
+    // TODO (b/238354685): Match interface style of Bounds after the API is fully backported
+    fun getWindowInsets(): WindowInsetsCompat {
+        return _windowInsetsCompat
     }
 
     override fun equals(other: Any?): Boolean {
@@ -85,16 +90,11 @@
     override fun hashCode(): Int {
         var result = _bounds.hashCode()
         result = 31 * result + _windowInsetsCompat.hashCode()
+        result = 31 * result + density.hashCode()
         return result
     }
 
-    /**
-     * Returns the [WindowInsetsCompat] of the area associated with this window or visual context.
-     */
-    @ExperimentalWindowApi
-    @RequiresApi(VERSION_CODES.R)
-    // TODO (b/238354685): Match interface style of Bounds after the API is fully backported
-    fun getWindowInsets(): WindowInsetsCompat {
-        return _windowInsetsCompat
+    override fun toString(): String {
+        return "WindowMetrics(_bounds=$_bounds, _windowInsetsCompat=$_windowInsetsCompat, density=$density)"
     }
 }
diff --git a/window/window/src/main/java/androidx/window/layout/adapter/WindowSizeClassFactory.kt b/window/window/src/main/java/androidx/window/layout/adapter/WindowSizeClassFactory.kt
new file mode 100644
index 0000000..686173e
--- /dev/null
+++ b/window/window/src/main/java/androidx/window/layout/adapter/WindowSizeClassFactory.kt
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@file:JvmName("WindowSizeClassFactory")
+
+package androidx.window.layout.adapter
+
+import androidx.window.core.layout.WindowSizeClass
+import androidx.window.core.layout.computeWindowSizeClass
+import androidx.window.layout.WindowMetrics
+
+/** A convenience function for computing the [WindowSizeClass] from the [WindowMetrics] */
+fun Set.computeWindowSizeClass(windowMetrics: WindowMetrics): WindowSizeClass {
+    val density = windowMetrics.density
+    val widthDp = (windowMetrics.bounds.width() * 160) / density
+    val heightDp = (windowMetrics.bounds.height() * 160) / density
+    return computeWindowSizeClass(widthDp, heightDp)
+}