Merge "Add support for parsing states." into sc-v2-dev
This commit is contained in:
@@ -30,18 +30,21 @@ import java.util.regex.Pattern;
|
|||||||
/** Wrapper for both Extension and Sidecar versions of DisplayFeature. */
|
/** Wrapper for both Extension and Sidecar versions of DisplayFeature. */
|
||||||
final class CommonDisplayFeature implements DisplayFeature {
|
final class CommonDisplayFeature implements DisplayFeature {
|
||||||
private static final Pattern FEATURE_PATTERN =
|
private static final Pattern FEATURE_PATTERN =
|
||||||
Pattern.compile("([a-z]+)-\\[(\\d+),(\\d+),(\\d+),(\\d+)]");
|
Pattern.compile("([a-z]+)-\\[(\\d+),(\\d+),(\\d+),(\\d+)]-?(flat|half-opened)?");
|
||||||
|
|
||||||
private static final String FEATURE_TYPE_FOLD = "fold";
|
private static final String FEATURE_TYPE_FOLD = "fold";
|
||||||
private static final String FEATURE_TYPE_HINGE = "hinge";
|
private static final String FEATURE_TYPE_HINGE = "hinge";
|
||||||
|
|
||||||
|
private static final String PATTERN_STATE_FLAT = "flat";
|
||||||
|
private static final String PATTERN_STATE_HALF_OPENED = "half-opened";
|
||||||
|
|
||||||
// TODO(b/183049815): Support feature strings that include the state of the feature.
|
// TODO(b/183049815): Support feature strings that include the state of the feature.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses a display feature from a string.
|
* Parses a display feature from a string.
|
||||||
*
|
*
|
||||||
* @throws IllegalArgumentException if the provided string is improperly formatted or could not
|
* @throws IllegalArgumentException if the provided string is improperly formatted or could not
|
||||||
* otherwise be parsed.
|
* otherwise be parsed.
|
||||||
*
|
|
||||||
* @see #FEATURE_PATTERN
|
* @see #FEATURE_PATTERN
|
||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
@@ -52,6 +55,7 @@ final class CommonDisplayFeature implements DisplayFeature {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
String featureType = featureMatcher.group(1);
|
String featureType = featureMatcher.group(1);
|
||||||
|
featureType = featureType == null ? "" : featureType;
|
||||||
int type;
|
int type;
|
||||||
switch (featureType) {
|
switch (featureType) {
|
||||||
case FEATURE_TYPE_FOLD:
|
case FEATURE_TYPE_FOLD:
|
||||||
@@ -73,8 +77,21 @@ final class CommonDisplayFeature implements DisplayFeature {
|
|||||||
if (isZero(featureRect)) {
|
if (isZero(featureRect)) {
|
||||||
throw new IllegalArgumentException("Feature has empty bounds: " + string);
|
throw new IllegalArgumentException("Feature has empty bounds: " + string);
|
||||||
}
|
}
|
||||||
|
String stateString = featureMatcher.group(6);
|
||||||
return new CommonDisplayFeature(type, null, featureRect);
|
stateString = stateString == null ? "" : stateString;
|
||||||
|
Integer state;
|
||||||
|
switch (stateString) {
|
||||||
|
case PATTERN_STATE_FLAT:
|
||||||
|
state = COMMON_STATE_FLAT;
|
||||||
|
break;
|
||||||
|
case PATTERN_STATE_HALF_OPENED:
|
||||||
|
state = COMMON_STATE_HALF_OPENED;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
state = null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return new CommonDisplayFeature(type, state, featureRect);
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
throw new IllegalArgumentException("Malformed feature description: " + string, e);
|
throw new IllegalArgumentException("Malformed feature description: " + string, e);
|
||||||
}
|
}
|
||||||
@@ -87,6 +104,7 @@ final class CommonDisplayFeature implements DisplayFeature {
|
|||||||
private final Rect mRect;
|
private final Rect mRect;
|
||||||
|
|
||||||
CommonDisplayFeature(int type, @Nullable Integer state, @NonNull Rect rect) {
|
CommonDisplayFeature(int type, @Nullable Integer state, @NonNull Rect rect) {
|
||||||
|
assertValidState(state);
|
||||||
this.mType = type;
|
this.mType = type;
|
||||||
this.mState = state;
|
this.mState = state;
|
||||||
if (rect.width() == 0 && rect.height() == 0) {
|
if (rect.width() == 0 && rect.height() == 0) {
|
||||||
@@ -125,4 +143,11 @@ final class CommonDisplayFeature implements DisplayFeature {
|
|||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(mType, mState, mRect);
|
return Objects.hash(mType, mState, mRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void assertValidState(@Nullable Integer state) {
|
||||||
|
if (state != null && state != COMMON_STATE_FLAT && state != COMMON_STATE_HALF_OPENED) {
|
||||||
|
throw new IllegalArgumentException("Invalid state: " + state
|
||||||
|
+ "must be either COMMON_STATE_FLAT or COMMON_STATE_HALF_OPENED");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,11 +16,15 @@
|
|||||||
|
|
||||||
package androidx.window.common;
|
package androidx.window.common;
|
||||||
|
|
||||||
|
import android.annotation.IntDef;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
|
||||||
/** Wrapper for both Extension and Sidecar versions of DisplayFeature. */
|
/** Wrapper for both Extension and Sidecar versions of DisplayFeature. */
|
||||||
public interface DisplayFeature {
|
public interface DisplayFeature {
|
||||||
/** Returns the type of the feature. */
|
/** Returns the type of the feature. */
|
||||||
@@ -28,9 +32,29 @@ public interface DisplayFeature {
|
|||||||
|
|
||||||
/** Returns the state of the feature, or {@code null} if the feature has no state. */
|
/** Returns the state of the feature, or {@code null} if the feature has no state. */
|
||||||
@Nullable
|
@Nullable
|
||||||
|
@State
|
||||||
Integer getState();
|
Integer getState();
|
||||||
|
|
||||||
/** Returns the bounds of the feature. */
|
/** Returns the bounds of the feature. */
|
||||||
@NonNull
|
@NonNull
|
||||||
Rect getRect();
|
Rect getRect();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A common state to represent a FLAT hinge. This is needed because the definitions in Sidecar
|
||||||
|
* and Extensions do not match exactly.
|
||||||
|
*/
|
||||||
|
int COMMON_STATE_FLAT = 3;
|
||||||
|
/**
|
||||||
|
* A common state to represent a HALF_OPENED hinge. This is needed because the definitions in
|
||||||
|
* Sidecar and Extensions do not match exactly.
|
||||||
|
*/
|
||||||
|
int COMMON_STATE_HALF_OPENED = 2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The possible states for a folding hinge.
|
||||||
|
*/
|
||||||
|
@IntDef({COMMON_STATE_FLAT, COMMON_STATE_HALF_OPENED})
|
||||||
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
|
@interface State {}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -122,8 +122,19 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
|
|||||||
private int getFeatureState(DisplayFeature feature) {
|
private int getFeatureState(DisplayFeature feature) {
|
||||||
Integer featureState = feature.getState();
|
Integer featureState = feature.getState();
|
||||||
Optional<Integer> posture = mDevicePostureProducer.getData();
|
Optional<Integer> posture = mDevicePostureProducer.getData();
|
||||||
int fallbackPosture = posture.orElse(FoldingFeature.STATE_FLAT);
|
int fallbackPosture = posture.orElse(DisplayFeature.COMMON_STATE_FLAT);
|
||||||
return featureState == null ? fallbackPosture : featureState;
|
int displayFeatureState = featureState == null ? fallbackPosture : featureState;
|
||||||
|
return convertToExtensionState(displayFeatureState);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int convertToExtensionState(int state) {
|
||||||
|
switch (state) {
|
||||||
|
case DisplayFeature.COMMON_STATE_FLAT:
|
||||||
|
return FoldingFeature.STATE_FLAT;
|
||||||
|
case DisplayFeature.COMMON_STATE_HALF_OPENED:
|
||||||
|
return FoldingFeature.STATE_HALF_OPENED;
|
||||||
|
}
|
||||||
|
return FoldingFeature.STATE_FLAT;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onDisplayFeaturesChanged() {
|
private void onDisplayFeaturesChanged() {
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ import androidx.window.util.DataProducer;
|
|||||||
import androidx.window.util.PriorityDataProducer;
|
import androidx.window.util.PriorityDataProducer;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
@@ -47,6 +48,7 @@ import java.util.Optional;
|
|||||||
*/
|
*/
|
||||||
class SampleSidecarImpl extends StubSidecar {
|
class SampleSidecarImpl extends StubSidecar {
|
||||||
private static final String TAG = "SampleSidecar";
|
private static final String TAG = "SampleSidecar";
|
||||||
|
private static final boolean DEBUG = false;
|
||||||
|
|
||||||
private final SettingsDevicePostureProducer mSettingsDevicePostureProducer;
|
private final SettingsDevicePostureProducer mSettingsDevicePostureProducer;
|
||||||
private final DataProducer<Integer> mDevicePostureProducer;
|
private final DataProducer<Integer> mDevicePostureProducer;
|
||||||
@@ -88,10 +90,30 @@ class SampleSidecarImpl extends StubSidecar {
|
|||||||
Optional<Integer> posture = mDevicePostureProducer.getData();
|
Optional<Integer> posture = mDevicePostureProducer.getData();
|
||||||
|
|
||||||
SidecarDeviceState deviceState = new SidecarDeviceState();
|
SidecarDeviceState deviceState = new SidecarDeviceState();
|
||||||
deviceState.posture = posture.orElse(SidecarDeviceState.POSTURE_UNKNOWN);
|
deviceState.posture = posture.orElse(deviceStateFromFeature());
|
||||||
return deviceState;
|
return deviceState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int deviceStateFromFeature() {
|
||||||
|
List<DisplayFeature> storedFeatures = mDisplayFeatureProducer.getData()
|
||||||
|
.orElse(Collections.emptyList());
|
||||||
|
for (int i = 0; i < storedFeatures.size(); i++) {
|
||||||
|
DisplayFeature feature = storedFeatures.get(i);
|
||||||
|
final int state = feature.getState() == null ? -1 : feature.getState();
|
||||||
|
if (DEBUG && feature.getState() == null) {
|
||||||
|
Log.d(TAG, "feature#getState was null for DisplayFeature: " + feature);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (state) {
|
||||||
|
case DisplayFeature.COMMON_STATE_FLAT:
|
||||||
|
return SidecarDeviceState.POSTURE_OPENED;
|
||||||
|
case DisplayFeature.COMMON_STATE_HALF_OPENED:
|
||||||
|
return SidecarDeviceState.POSTURE_HALF_OPENED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return SidecarDeviceState.POSTURE_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public SidecarWindowLayoutInfo getWindowLayoutInfo(@NonNull IBinder windowToken) {
|
public SidecarWindowLayoutInfo getWindowLayoutInfo(@NonNull IBinder windowToken) {
|
||||||
|
|||||||
Reference in New Issue
Block a user