HardwareFoldingFeature.kt
/*
* Copyright 2021 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.
*/
package androidx.window.layout
import android.graphics.Rect
import androidx.window.core.Bounds
/**
* @param [type] that is either [HardwareFoldingFeature.Type.FOLD] or
* [HardwareFoldingFeature.Type.HINGE] @param [state] the physical state of the hinge that is
* either [FoldingFeature.State.FLAT] or [FoldingFeature.State.HALF_OPENED]
*/
internal class HardwareFoldingFeature(
/**
* The bounding rectangle of the feature within the application window in the window
* coordinate space.
*/
private val featureBounds: Bounds,
internal val type: Type,
override val state: FoldingFeature.State
) : FoldingFeature {
init {
validateFeatureBounds(featureBounds)
}
override val bounds: Rect
get() = featureBounds.toRect()
override val isSeparating: Boolean
get() = when {
type == Type.HINGE -> true
type == Type.FOLD && state == FoldingFeature.State.HALF_OPENED -> true
else -> false
}
override val occlusionType: FoldingFeature.OcclusionType
get() = if (featureBounds.width == 0 || featureBounds.height == 0) {
FoldingFeature.OcclusionType.NONE
} else {
FoldingFeature.OcclusionType.FULL
}
override val orientation: FoldingFeature.Orientation
get() {
return if (featureBounds.width > featureBounds.height) {
FoldingFeature.Orientation.HORIZONTAL
} else {
FoldingFeature.Orientation.VERTICAL
}
}
override fun toString(): String {
return "${HardwareFoldingFeature::class.java.simpleName} { $featureBounds, type=$type, " +
"state=$state }"
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as HardwareFoldingFeature
if (featureBounds != other.featureBounds) return false
if (type != other.type) return false
if (state != other.state) return false
return true
}
override fun hashCode(): Int {
var result = featureBounds.hashCode()
result = 31 * result + type.hashCode()
result = 31 * result + state.hashCode()
return result
}
internal companion object {
/**
* Verifies the bounds of the folding feature.
*/
internal fun validateFeatureBounds(bounds: Bounds) {
require(!(bounds.width == 0 && bounds.height == 0)) { "Bounds must be non zero" }
require(!(bounds.left != 0 && bounds.top != 0)) {
"Bounding rectangle must start at the top or left window edge for folding features"
}
}
}
/**
* Represents the type of hinge.
*/
internal class Type private constructor(private val description: String) {
override fun toString(): String {
return description
}
internal companion object {
/**
* Represent a continuous screen that folds.
*/
val FOLD: Type = Type("FOLD")
/**
* Represents a hinge connecting two separate display panels.
*/
val HINGE: Type = Type("HINGE")
}
}
}