Merge "[1/n] Creates OptPropFactory to simplify OptIn and OptOut properties" into main
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index c1af719..0a26490 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -3065,6 +3065,7 @@
}
public static final class DreamService.DreamMetadata {
+ field @FlaggedApi("android.service.controls.flags.home_panel_dream") @NonNull public final int dreamCategory;
field @Nullable public final android.graphics.drawable.Drawable previewImage;
field @Nullable public final android.content.ComponentName settingsActivity;
field @NonNull public final boolean showComplications;
diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java
index 2d657c2..4060b24 100644
--- a/core/java/android/service/dreams/DreamService.java
+++ b/core/java/android/service/dreams/DreamService.java
@@ -18,7 +18,9 @@
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import android.annotation.FlaggedApi;
import android.annotation.IdRes;
+import android.annotation.IntDef;
import android.annotation.LayoutRes;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -47,6 +49,7 @@
import android.os.PowerManager;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.service.controls.flags.Flags;
import android.util.AttributeSet;
import android.util.Log;
import android.util.MathUtils;
@@ -76,6 +79,8 @@
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.function.Consumer;
/**
@@ -217,6 +222,33 @@
*/
public static final boolean DEFAULT_SHOW_COMPLICATIONS = false;
+ /**
+ * The default value for dream category
+ * @hide
+ */
+ public static final int DREAM_CATEGORY_DEFAULT = 0;
+
+ /**
+ * Dream category for Low Light Dream
+ * @hide
+ */
+ public static final int DREAM_CATEGORY_LOW_LIGHT = 1 << 0;
+
+ /**
+ * Dream category for Home Panel Dream
+ * @hide
+ */
+ public static final int DREAM_CATEGORY_HOME_PANEL = 1 << 1;
+
+ /** @hide */
+ @IntDef(flag = true, prefix = {"DREAM_CATEGORY"}, value = {
+ DREAM_CATEGORY_DEFAULT,
+ DREAM_CATEGORY_LOW_LIGHT,
+ DREAM_CATEGORY_HOME_PANEL
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ @interface DreamCategory {}
+
private final IDreamManager mDreamManager;
private final Handler mHandler = new Handler(Looper.getMainLooper());
private IBinder mDreamToken;
@@ -1122,12 +1154,15 @@
try (TypedArray rawMetadata = readMetadata(pm, serviceInfo)) {
if (rawMetadata == null) return null;
return new DreamMetadata(
- convertToComponentName(rawMetadata.getString(
+ convertToComponentName(
+ rawMetadata.getString(
com.android.internal.R.styleable.Dream_settingsActivity), serviceInfo),
rawMetadata.getDrawable(
com.android.internal.R.styleable.Dream_previewImage),
rawMetadata.getBoolean(R.styleable.Dream_showClockAndComplications,
- DEFAULT_SHOW_COMPLICATIONS));
+ DEFAULT_SHOW_COMPLICATIONS),
+ rawMetadata.getInt(R.styleable.Dream_dreamCategory, DREAM_CATEGORY_DEFAULT)
+ );
}
}
@@ -1543,11 +1578,23 @@
@NonNull
public final boolean showComplications;
- DreamMetadata(ComponentName settingsActivity, Drawable previewImage,
- boolean showComplications) {
+ @NonNull
+ @FlaggedApi(Flags.FLAG_HOME_PANEL_DREAM)
+ public final int dreamCategory;
+
+ DreamMetadata(
+ ComponentName settingsActivity,
+ Drawable previewImage,
+ boolean showComplications,
+ int dreamCategory) {
this.settingsActivity = settingsActivity;
this.previewImage = previewImage;
this.showComplications = showComplications;
+ if (Flags.homePanelDream()) {
+ this.dreamCategory = dreamCategory;
+ } else {
+ this.dreamCategory = DREAM_CATEGORY_DEFAULT;
+ }
}
}
}
diff --git a/core/java/android/view/ImeInsetsSourceConsumer.java b/core/java/android/view/ImeInsetsSourceConsumer.java
index 821e13d..b300022 100644
--- a/core/java/android/view/ImeInsetsSourceConsumer.java
+++ b/core/java/android/view/ImeInsetsSourceConsumer.java
@@ -49,9 +49,9 @@
/**
* Tracks whether we have an outstanding request from the IME to show, but weren't able to
- * execute it because we didn't have control yet.
+ * execute it because we didn't have control yet, or we didn't have a leash on the control yet.
*/
- private boolean mIsRequestedVisibleAwaitingControl;
+ private boolean mIsRequestedVisibleAwaitingLeash;
public ImeInsetsSourceConsumer(
int id, InsetsState state, Supplier<Transaction> transactionSupplier,
@@ -68,7 +68,7 @@
}
final boolean insetsChanged = super.onAnimationStateChanged(running);
if (!isShowRequested()) {
- mIsRequestedVisibleAwaitingControl = false;
+ mIsRequestedVisibleAwaitingLeash = false;
if (!running && !mHasPendingRequest) {
final var statsToken = ImeTracker.forLogging().onStart(ImeTracker.TYPE_HIDE,
ImeTracker.ORIGIN_CLIENT,
@@ -91,8 +91,8 @@
public void onWindowFocusGained(boolean hasViewFocus) {
super.onWindowFocusGained(hasViewFocus);
getImm().registerImeConsumer(this);
- if ((mController.getRequestedVisibleTypes() & getType()) != 0 && getControl() == null) {
- mIsRequestedVisibleAwaitingControl = true;
+ if ((mController.getRequestedVisibleTypes() & getType()) != 0 && !hasLeash()) {
+ mIsRequestedVisibleAwaitingLeash = true;
}
}
@@ -100,7 +100,7 @@
public void onWindowFocusLost() {
super.onWindowFocusLost();
getImm().unregisterImeConsumer(this);
- mIsRequestedVisibleAwaitingControl = false;
+ mIsRequestedVisibleAwaitingLeash = false;
}
@Override
@@ -130,15 +130,15 @@
ImeTracker.forLogging().onProgress(statsToken,
ImeTracker.PHASE_CLIENT_INSETS_CONSUMER_REQUEST_SHOW);
- if (getControl() == null) {
- // If control is null, schedule to show IME when control is available.
- mIsRequestedVisibleAwaitingControl = true;
+ if (!hasLeash()) {
+ // If control or leash is null, schedule to show IME when both available.
+ mIsRequestedVisibleAwaitingLeash = true;
}
// If we had a request before to show from IME (tracked with mImeRequestedShow), reaching
// this code here means that we now got control, so we can start the animation immediately.
// If client window is trying to control IME and IME is already visible, it is immediate.
if (fromIme
- || (mState.isSourceOrDefaultVisible(getId(), getType()) && getControl() != null)) {
+ || (mState.isSourceOrDefaultVisible(getId(), getType()) && hasLeash())) {
return ShowResult.SHOW_IMMEDIATELY;
}
@@ -148,9 +148,9 @@
void requestHide(boolean fromIme, @Nullable ImeTracker.Token statsToken) {
if (!fromIme) {
- // Create a new token to track the hide request when we have control,
+ // Create a new token to track the hide request when we have control and leash,
// as we use the passed in token for the insets animation already.
- final var notifyStatsToken = getControl() != null
+ final var notifyStatsToken = hasLeash()
? ImeTracker.forLogging().onStart(ImeTracker.TYPE_HIDE,
ImeTracker.ORIGIN_CLIENT,
SoftInputShowHideReason.HIDE_SOFT_INPUT_REQUEST_HIDE_WITH_CONTROL,
@@ -176,7 +176,7 @@
ImeTracker.PHASE_CLIENT_INSETS_CONSUMER_NOTIFY_HIDDEN);
getImm().notifyImeHidden(mController.getHost().getWindowToken(), statsToken);
- mIsRequestedVisibleAwaitingControl = false;
+ mIsRequestedVisibleAwaitingLeash = false;
Trace.asyncTraceEnd(TRACE_TAG_VIEW, "IC.hideRequestFromApi", 0);
}
@@ -196,19 +196,28 @@
if (!super.setControl(control, showTypes, hideTypes)) {
return false;
}
- if (control == null && !mIsRequestedVisibleAwaitingControl) {
+ final boolean hasLeash = control != null && control.getLeash() != null;
+ if (!hasLeash && !mIsRequestedVisibleAwaitingLeash) {
mController.setRequestedVisibleTypes(0 /* visibleTypes */, getType());
removeSurface();
}
- if (control != null) {
- mIsRequestedVisibleAwaitingControl = false;
+ if (hasLeash) {
+ mIsRequestedVisibleAwaitingLeash = false;
}
return true;
}
@Override
protected boolean isRequestedVisibleAwaitingControl() {
- return super.isRequestedVisibleAwaitingControl() || mIsRequestedVisibleAwaitingControl;
+ return super.isRequestedVisibleAwaitingControl() || mIsRequestedVisibleAwaitingLeash;
+ }
+
+ /**
+ * Checks whether the consumer has an insets source control with a leash.
+ */
+ private boolean hasLeash() {
+ final var control = getControl();
+ return control != null && control.getLeash() != null;
}
@Override
@@ -224,7 +233,7 @@
public void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
super.dumpDebug(proto, INSETS_SOURCE_CONSUMER);
- proto.write(IS_REQUESTED_VISIBLE_AWAITING_CONTROL, mIsRequestedVisibleAwaitingControl);
+ proto.write(IS_REQUESTED_VISIBLE_AWAITING_CONTROL, mIsRequestedVisibleAwaitingLeash);
proto.write(HAS_PENDING_REQUEST, mHasPendingRequest);
proto.end(token);
}
diff --git a/core/java/android/window/TransitionInfo.java b/core/java/android/window/TransitionInfo.java
index 3685bba..5227724 100644
--- a/core/java/android/window/TransitionInfo.java
+++ b/core/java/android/window/TransitionInfo.java
@@ -542,6 +542,9 @@
// independent either.
if (change.getMode() == TRANSIT_CHANGE) return false;
+ // Always fold the activity embedding change into the parent change.
+ if (change.hasFlags(FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY)) return false;
+
TransitionInfo.Change parentChg = info.getChange(change.getParent());
while (parentChg != null) {
// If the parent is a visibility change, it will include the results of all child
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 48cf09a..c77ee43 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -8988,6 +8988,14 @@
<!-- Whether to show clock and other complications such as weather in the overlay. Default
to true. Note that the overlay on dreams is currently only supported on tablets. -->
<attr name="showClockAndComplications" format="boolean" />
+
+ <!-- Dream Category to determine the type of dream. Default to default.
+ @hide -->
+ <attr name="dreamCategory" format="integer">
+ <flag name="none" value="0x0" />
+ <flag name="low_light" value="0x1" />
+ <flag name="home_panel" value="0x2" />
+ </attr>
</declare-styleable>
<!-- Use <code>trust-agent</code> as the root tag of the XML resource that
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index b879c97..417c6df 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -238,204 +238,204 @@
<color name="conversation_important_highlight">#F9AB00</color>
- <!-- Lightest shade of the accent color used by the system. White.
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent1_0">#ffffff</color>
- <!-- Shade of the accent system color at 99% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent1_10">#F9FCFF</color>
- <!-- Shade of the accent system color at 95% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent1_50">#E0F3FF</color>
- <!-- Shade of the accent system color at 90% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent1_100">#C1E8FF</color>
- <!-- Shade of the accent system color at 80% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent1_200">#76D1FF</color>
- <!-- Shade of the accent system color at 70% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent1_300">#4BB6E8</color>
- <!-- Shade of the accent system color at 60% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent1_400">#219BCC</color>
- <!-- Shade of the accent system color at 49.6% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent1_500">#007FAC</color>
- <!-- Shade of the accent system color at 40% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent1_600">#00668B</color>
- <!-- Shade of the accent system color at 30% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent1_700">#004C69</color>
- <!-- Shade of the accent system color at 20% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent1_800">#003549</color>
- <!-- Shade of the accent system color at 10% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent1_900">#001E2C</color>
- <!-- Darkest shade of the accent color used by the system. Black.
- This value can be overlaid at runtime by OverlayManager RROs. -->
+ <!--Lightest shade of the Primary color used by the system. White.
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent1_0">#FFFFFF</color>
+ <!--Shade of the Primary system color at 99% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent1_10">#FEFBFF</color>
+ <!--Shade of the Primary system color at 95% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent1_50">#EEF0FF</color>
+ <!--Shade of the Primary system color at 90% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent1_100">#D9E2FF</color>
+ <!--Shade of the Primary system color at 80% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent1_200">#B0C6FF</color>
+ <!--Shade of the Primary system color at 70% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent1_300">#94AAE4</color>
+ <!--Shade of the Primary system color at 60% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent1_400">#7A90C8</color>
+ <!--Shade of the Primary system color at 50% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent1_500">#6076AC</color>
+ <!--Shade of the Primary system color at 40% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent1_600">#475D92</color>
+ <!--Shade of the Primary system color at 30% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent1_700">#2F4578</color>
+ <!--Shade of the Primary system color at 20% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent1_800">#152E60</color>
+ <!--Shade of the Primary system color at 10% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent1_900">#001945</color>
+ <!--Darkest shade of the Primary color used by the system. Black.
+ This value can be overlaid at runtime by OverlayManager RROs.-->
<color name="system_accent1_1000">#000000</color>
- <!-- Lightest shade of the secondary accent color used by the system. White.
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent2_0">#ffffff</color>
- <!-- Shade of the secondary accent system color at 99% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent2_10">#F9FCFF</color>
- <!-- Shade of the secondary accent system color at 95% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent2_50">#E0F3FF</color>
- <!-- Shade of the secondary accent system color at 90% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent2_100">#D1E5F4</color>
- <!-- Shade of the secondary accent system color at 80% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent2_200">#B5CAD7</color>
- <!-- Shade of the secondary accent system color at 70% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent2_300">#9AAEBB</color>
- <!-- Shade of the secondary accent system color at 60% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent2_400">#8094A0</color>
- <!-- Shade of the secondary accent system color at 49.6% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent2_500">#657985</color>
- <!-- Shade of the secondary accent system color at 40% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent2_600">#4E616C</color>
- <!-- Shade of the secondary accent system color at 30% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent2_700">#374955</color>
- <!-- Shade of the secondary accent system color at 20% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent2_800">#20333D</color>
- <!-- Shade of the secondary accent system color at 10% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent2_900">#091E28</color>
- <!-- Darkest shade of the secondary accent color used by the system. Black.
- This value can be overlaid at runtime by OverlayManager RROs. -->
+ <!--Lightest shade of the Secondary color used by the system. White.
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent2_0">#FFFFFF</color>
+ <!--Shade of the Secondary system color at 99% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent2_10">#FEFBFF</color>
+ <!--Shade of the Secondary system color at 95% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent2_50">#EEF0FF</color>
+ <!--Shade of the Secondary system color at 90% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent2_100">#DCE2F9</color>
+ <!--Shade of the Secondary system color at 80% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent2_200">#C0C6DC</color>
+ <!--Shade of the Secondary system color at 70% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent2_300">#A4ABC1</color>
+ <!--Shade of the Secondary system color at 60% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent2_400">#8A90A5</color>
+ <!--Shade of the Secondary system color at 50% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent2_500">#70778B</color>
+ <!--Shade of the Secondary system color at 40% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent2_600">#575E71</color>
+ <!--Shade of the Secondary system color at 30% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent2_700">#404659</color>
+ <!--Shade of the Secondary system color at 20% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent2_800">#2A3042</color>
+ <!--Shade of the Secondary system color at 10% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent2_900">#151B2C</color>
+ <!--Darkest shade of the Secondary color used by the system. Black.
+ This value can be overlaid at runtime by OverlayManager RROs.-->
<color name="system_accent2_1000">#000000</color>
- <!-- Lightest shade of the tertiary accent color used by the system. White.
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent3_0">#ffffff</color>
- <!-- Shade of the tertiary accent system color at 99% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
+ <!--Lightest shade of the Tertiary color used by the system. White.
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent3_0">#FFFFFF</color>
+ <!--Shade of the Tertiary system color at 99% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
<color name="system_accent3_10">#FFFBFF</color>
- <!-- Shade of the tertiary accent system color at 95% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent3_50">#F5EEFF</color>
- <!-- Shade of the tertiary accent system color at 90% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent3_100">#E6DEFF</color>
- <!-- Shade of the tertiary accent system color at 80% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent3_200">#CAC1EA</color>
- <!-- Shade of the tertiary accent system color at 70% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent3_300">#AEA6CE</color>
- <!-- Shade of the tertiary accent system color at 60% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent3_400">#938CB1</color>
- <!-- Shade of the tertiary accent system color at 49% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent3_500">#787296</color>
- <!-- Shade of the tertiary accent system color at 40% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent3_600">#605A7C</color>
- <!-- Shade of the tertiary accent system color at 30% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent3_700">#484264</color>
- <!-- Shade of the tertiary accent system color at 20% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent3_800">#322C4C</color>
- <!-- Shade of the tertiary accent system color at 10% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent3_900">#1D1736</color>
- <!-- Darkest shade of the tertiary accent color used by the system. Black.
- This value can be overlaid at runtime by OverlayManager RROs. -->
+ <!--Shade of the Tertiary system color at 95% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent3_50">#FFEBFA</color>
+ <!--Shade of the Tertiary system color at 90% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent3_100">#FDD7FA</color>
+ <!--Shade of the Tertiary system color at 80% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent3_200">#E0BBDD</color>
+ <!--Shade of the Tertiary system color at 70% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent3_300">#C3A0C1</color>
+ <!--Shade of the Tertiary system color at 60% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent3_400">#A886A6</color>
+ <!--Shade of the Tertiary system color at 50% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent3_500">#8C6D8C</color>
+ <!--Shade of the Tertiary system color at 40% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent3_600">#725572</color>
+ <!--Shade of the Tertiary system color at 30% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent3_700">#593D59</color>
+ <!--Shade of the Tertiary system color at 20% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent3_800">#412742</color>
+ <!--Shade of the Tertiary system color at 10% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent3_900">#2A122C</color>
+ <!--Darkest shade of the Tertiary color used by the system. Black.
+ This value can be overlaid at runtime by OverlayManager RROs.-->
<color name="system_accent3_1000">#000000</color>
- <!-- Lightest shade of the neutral color used by the system. White.
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral1_0">#ffffff</color>
- <!-- Shade of the neutral system color at 99% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral1_10">#FCFCFF</color>
- <!-- Shade of the neutral system color at 95% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral1_50">#F0F0F3</color>
- <!-- Shade of the neutral system color at 90% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral1_100">#E1E3E5</color>
- <!-- Shade of the neutral system color at 80% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral1_200">#C5C7C9</color>
- <!-- Shade of the neutral system color at 70% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral1_300">#AAABAE</color>
- <!-- Shade of the neutral system color at 60% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral1_400">#8F9193</color>
- <!-- Shade of the neutral system color at 49% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral1_500">#747679</color>
- <!-- Shade of the neutral system color at 40% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral1_600">#5C5F61</color>
- <!-- Shade of the neutral system color at 30% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral1_700">#454749</color>
- <!-- Shade of the neutral system color at 20% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral1_800">#2E3133</color>
- <!-- Shade of the neutral system color at 10% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral1_900">#191C1E</color>
- <!-- Darkest shade of the neutral color used by the system. Black.
- This value can be overlaid at runtime by OverlayManager RROs. -->
+ <!--Lightest shade of the Neutral color used by the system. White.
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_neutral1_0">#FFFFFF</color>
+ <!--Shade of the Neutral system color at 99% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_neutral1_10">#FEFBFF</color>
+ <!--Shade of the Neutral system color at 95% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_neutral1_50">#F1F0F7</color>
+ <!--Shade of the Neutral system color at 90% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_neutral1_100">#E2E2E9</color>
+ <!--Shade of the Neutral system color at 80% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_neutral1_200">#C6C6CD</color>
+ <!--Shade of the Neutral system color at 70% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_neutral1_300">#ABABB1</color>
+ <!--Shade of the Neutral system color at 60% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_neutral1_400">#909097</color>
+ <!--Shade of the Neutral system color at 50% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_neutral1_500">#76777D</color>
+ <!--Shade of the Neutral system color at 40% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_neutral1_600">#5D5E64</color>
+ <!--Shade of the Neutral system color at 30% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_neutral1_700">#45464C</color>
+ <!--Shade of the Neutral system color at 20% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_neutral1_800">#2F3036</color>
+ <!--Shade of the Neutral system color at 10% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_neutral1_900">#1A1B20</color>
+ <!--Darkest shade of the Neutral color used by the system. Black.
+ This value can be overlaid at runtime by OverlayManager RROs.-->
<color name="system_neutral1_1000">#000000</color>
- <!-- Lightest shade of the secondary neutral color used by the system. White.
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral2_0">#ffffff</color>
- <!-- Shade of the secondary neutral system color at 99% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral2_10">#F9FCFF</color>
- <!-- Shade of the secondary neutral system color at 95% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral2_50">#EBF1F8</color>
- <!-- Shade of the secondary neutral system color at 90% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral2_100">#DCE3E9</color>
- <!-- Shade of the secondary neutral system color at 80% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral2_200">#C0C7CD</color>
- <!-- Shade of the secondary neutral system color at 70% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral2_300">#A5ACB2</color>
- <!-- Shade of the secondary neutral system color at 60% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral2_400">#8A9297</color>
- <!-- Shade of the secondary neutral system color at 49% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral2_500">#70777C</color>
- <!-- Shade of the secondary neutral system color at 40% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral2_600">#585F65</color>
- <!-- Shade of the secondary neutral system color at 30% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral2_700">#40484D</color>
- <!-- Shade of the secondary neutral system color at 20% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral2_800">#2A3136</color>
- <!-- Shade of the secondary neutral system color at 10% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral2_900">#161C20</color>
- <!-- Darkest shade of the secondary neutral color used by the system. Black.
- This value can be overlaid at runtime by OverlayManager RROs. -->
+ <!--Lightest shade of the Secondary Neutral color used by the system. White.
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_neutral2_0">#FFFFFF</color>
+ <!--Shade of the Secondary Neutral system color at 99% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_neutral2_10">#FEFBFF</color>
+ <!--Shade of the Secondary Neutral system color at 95% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_neutral2_50">#F0F0FA</color>
+ <!--Shade of the Secondary Neutral system color at 90% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_neutral2_100">#E1E2EC</color>
+ <!--Shade of the Secondary Neutral system color at 80% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_neutral2_200">#C5C6D0</color>
+ <!--Shade of the Secondary Neutral system color at 70% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_neutral2_300">#A9ABB4</color>
+ <!--Shade of the Secondary Neutral system color at 60% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_neutral2_400">#8F9099</color>
+ <!--Shade of the Secondary Neutral system color at 50% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_neutral2_500">#757780</color>
+ <!--Shade of the Secondary Neutral system color at 40% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_neutral2_600">#5C5E67</color>
+ <!--Shade of the Secondary Neutral system color at 30% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_neutral2_700">#44464F</color>
+ <!--Shade of the Secondary Neutral system color at 20% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_neutral2_800">#2E3038</color>
+ <!--Shade of the Secondary Neutral system color at 10% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_neutral2_900">#191B23</color>
+ <!--Darkest shade of the Secondary Neutral color used by the system. Black.
+ This value can be overlaid at runtime by OverlayManager RROs.-->
<color name="system_neutral2_1000">#000000</color>
<!-- Lightest shade of the error color used by the system. White.
@@ -480,106 +480,106 @@
<!-- Colors used in Android system, from design system.
These values can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_primary_container_light">#D8E2FF</color>
- <color name="system_on_primary_container_light">#001A41</color>
- <color name="system_primary_light">#445E91</color>
+ <color name="system_primary_container_light">#5E73A9</color>
+ <color name="system_on_primary_container_light">#FFFFFF</color>
+ <color name="system_primary_light">#2A4174</color>
<color name="system_on_primary_light">#FFFFFF</color>
- <color name="system_secondary_container_light">#DBE2F9</color>
- <color name="system_on_secondary_container_light">#141B2C</color>
- <color name="system_secondary_light">#575E71</color>
+ <color name="system_secondary_container_light">#6E7488</color>
+ <color name="system_on_secondary_container_light">#FFFFFF</color>
+ <color name="system_secondary_light">#3C4255</color>
<color name="system_on_secondary_light">#FFFFFF</color>
- <color name="system_tertiary_container_light">#FBD7FC</color>
- <color name="system_on_tertiary_container_light">#29132D</color>
- <color name="system_tertiary_light">#715573</color>
+ <color name="system_tertiary_container_light">#8A6A89</color>
+ <color name="system_on_tertiary_container_light">#FFFFFF</color>
+ <color name="system_tertiary_light">#553A55</color>
<color name="system_on_tertiary_light">#FFFFFF</color>
- <color name="system_background_light">#FAF9FD</color>
- <color name="system_on_background_light">#1B1B1F</color>
- <color name="system_surface_light">#FAF9FD</color>
- <color name="system_on_surface_light">#1B1B1F</color>
- <color name="system_surface_container_low_light">#F5F3F7</color>
+ <color name="system_background_light">#FAF8FF</color>
+ <color name="system_on_background_light">#1A1B20</color>
+ <color name="system_surface_light">#FAF8FF</color>
+ <color name="system_on_surface_light">#1A1B20</color>
+ <color name="system_surface_container_low_light">#F4F3FA</color>
<color name="system_surface_container_lowest_light">#FFFFFF</color>
- <color name="system_surface_container_light">#EFEDF1</color>
- <color name="system_surface_container_high_light">#E9E7EC</color>
- <color name="system_surface_container_highest_light">#E3E2E6</color>
- <color name="system_surface_bright_light">#FAF9FD</color>
- <color name="system_surface_dim_light">#DBD9DD</color>
+ <color name="system_surface_container_light">#EEEDF4</color>
+ <color name="system_surface_container_high_light">#E8E7EF</color>
+ <color name="system_surface_container_highest_light">#E2E2E9</color>
+ <color name="system_surface_bright_light">#FAF8FF</color>
+ <color name="system_surface_dim_light">#DAD9E0</color>
<color name="system_surface_variant_light">#E1E2EC</color>
- <color name="system_on_surface_variant_light">#44474F</color>
- <color name="system_outline_light">#72747D</color>
- <color name="system_outline_variant_light">#C4C7C5</color>
- <color name="system_error_light">#C00003</color>
+ <color name="system_on_surface_variant_light">#40434B</color>
+ <color name="system_outline_light">#5D5F67</color>
+ <color name="system_outline_variant_light">#797A83</color>
+ <color name="system_error_light">#8C0009</color>
<color name="system_on_error_light">#FFFFFF</color>
- <color name="system_error_container_light">#FFDAD5</color>
- <color name="system_on_error_container_light">#410000</color>
- <color name="system_primary_fixed">#D8E2FF</color>
- <color name="system_primary_fixed_dim">#ADC6FF</color>
- <color name="system_on_primary_fixed">#001A41</color>
- <color name="system_on_primary_fixed_variant">#2B4678</color>
- <color name="system_secondary_fixed">#DBE2F9</color>
- <color name="system_secondary_fixed_dim">#BFC6DC</color>
- <color name="system_on_secondary_fixed">#141B2C</color>
- <color name="system_on_secondary_fixed_variant">#3F4759</color>
- <color name="system_tertiary_fixed">#FBD7FC</color>
- <color name="system_tertiary_fixed_dim">#DEBCDF</color>
- <color name="system_on_tertiary_fixed">#29132D</color>
- <color name="system_on_tertiary_fixed_variant">#583E5B</color>
- <color name="system_control_activated_light">#D8E2FF</color>
- <color name="system_control_normal_light">#44474F</color>
- <color name="system_control_highlight_light">#1F000000</color>
- <color name="system_text_primary_inverse_light">#E3E2E6</color>
- <color name="system_text_secondary_and_tertiary_inverse_light">#C4C6D0</color>
- <color name="system_text_primary_inverse_disable_only_light">#E3E2E6</color>
- <color name="system_text_secondary_and_tertiary_inverse_disabled_light">#E3E2E6</color>
- <color name="system_text_hint_inverse_light">#E3E2E6</color>
- <color name="system_palette_key_color_primary_light">#5D77AC</color>
- <color name="system_palette_key_color_secondary_light">#6C7488</color>
- <color name="system_palette_key_color_tertiary_light">#907292</color>
- <color name="system_palette_key_color_neutral_light">#838387</color>
- <color name="system_palette_key_color_neutral_variant_light">#777982</color>
- <color name="system_primary_container_dark">#2B4678</color>
- <color name="system_on_primary_container_dark">#D8E2FF</color>
- <color name="system_primary_dark">#ADC6FF</color>
- <color name="system_on_primary_dark">#102F60</color>
- <color name="system_secondary_container_dark">#3F4759</color>
- <color name="system_on_secondary_container_dark">#DBE2F9</color>
- <color name="system_secondary_dark">#BFC6DC</color>
- <color name="system_on_secondary_dark">#293041</color>
- <color name="system_tertiary_container_dark">#583E5B</color>
- <color name="system_on_tertiary_container_dark">#FBD7FC</color>
- <color name="system_tertiary_dark">#DEBCDF</color>
- <color name="system_on_tertiary_dark">#402843</color>
- <color name="system_background_dark">#121316</color>
- <color name="system_on_background_dark">#E3E2E6</color>
- <color name="system_surface_dark">#121316</color>
- <color name="system_on_surface_dark">#E3E2E6</color>
- <color name="system_surface_container_low_dark">#1B1B1F</color>
- <color name="system_surface_container_lowest_dark">#0D0E11</color>
- <color name="system_surface_container_dark">#1F1F23</color>
- <color name="system_surface_container_high_dark">#292A2D</color>
- <color name="system_surface_container_highest_dark">#343538</color>
- <color name="system_surface_bright_dark">#38393C</color>
- <color name="system_surface_dim_dark">#121316</color>
- <color name="system_surface_variant_dark">#44474F</color>
- <color name="system_on_surface_variant_dark">#C4C6D0</color>
- <color name="system_outline_dark">#8E9099</color>
- <color name="system_outline_variant_dark">#444746</color>
- <color name="system_error_dark">#FFB4A8</color>
- <color name="system_on_error_dark">#690001</color>
- <color name="system_error_container_dark">#930001</color>
- <color name="system_on_error_container_dark">#FFDAD5</color>
- <color name="system_control_activated_dark">#2B4678</color>
- <color name="system_control_normal_dark">#C4C6D0</color>
- <color name="system_control_highlight_dark">#33FFFFFF</color>
- <color name="system_text_primary_inverse_dark">#1B1B1F</color>
- <color name="system_text_secondary_and_tertiary_inverse_dark">#44474F</color>
- <color name="system_text_primary_inverse_disable_only_dark">#1B1B1F</color>
- <color name="system_text_secondary_and_tertiary_inverse_disabled_dark">#1B1B1F</color>
- <color name="system_text_hint_inverse_dark">#1B1B1F</color>
- <color name="system_palette_key_color_primary_dark">#5D77AC</color>
- <color name="system_palette_key_color_secondary_dark">#6C7488</color>
- <color name="system_palette_key_color_tertiary_dark">#907292</color>
- <color name="system_palette_key_color_neutral_dark">#838387</color>
- <color name="system_palette_key_color_neutral_variant_dark">#777982</color>
+ <color name="system_error_container_light">#DA342E</color>
+ <color name="system_on_error_container_light">#FFFFFF</color>
+ <color name="system_control_activated_light">#D9E2FF</color>
+ <color name="system_control_normal_light">#44464F</color>
+ <color name="system_control_highlight_light">#000000</color>
+ <color name="system_text_primary_inverse_light">#E2E2E9</color>
+ <color name="system_text_secondary_and_tertiary_inverse_light">#C5C6D0</color>
+ <color name="system_text_primary_inverse_disable_only_light">#E2E2E9</color>
+ <color name="system_text_secondary_and_tertiary_inverse_disabled_light">#E2E2E9</color>
+ <color name="system_text_hint_inverse_light">#E2E2E9</color>
+ <color name="system_palette_key_color_primary_light">#6076AC</color>
+ <color name="system_palette_key_color_secondary_light">#70778B</color>
+ <color name="system_palette_key_color_tertiary_light">#8C6D8C</color>
+ <color name="system_palette_key_color_neutral_light">#76777D</color>
+ <color name="system_palette_key_color_neutral_variant_light">#757780</color>
+ <color name="system_primary_container_dark">#7A90C8</color>
+ <color name="system_on_primary_container_dark">#000000</color>
+ <color name="system_primary_dark">#B7CAFF</color>
+ <color name="system_on_primary_dark">#00143B</color>
+ <color name="system_secondary_container_dark">#8A90A5</color>
+ <color name="system_on_secondary_container_dark">#000000</color>
+ <color name="system_secondary_dark">#C4CAE1</color>
+ <color name="system_on_secondary_dark">#0F1626</color>
+ <color name="system_tertiary_container_dark">#A886A6</color>
+ <color name="system_on_tertiary_container_dark">#000000</color>
+ <color name="system_tertiary_dark">#E4BFE2</color>
+ <color name="system_on_tertiary_dark">#240D26</color>
+ <color name="system_background_dark">#121318</color>
+ <color name="system_on_background_dark">#E2E2E9</color>
+ <color name="system_surface_dark">#121318</color>
+ <color name="system_on_surface_dark">#FCFAFF</color>
+ <color name="system_surface_container_low_dark">#1A1B20</color>
+ <color name="system_surface_container_lowest_dark">#0C0E13</color>
+ <color name="system_surface_container_dark">#1E1F25</color>
+ <color name="system_surface_container_high_dark">#282A2F</color>
+ <color name="system_surface_container_highest_dark">#33343A</color>
+ <color name="system_surface_bright_dark">#38393F</color>
+ <color name="system_surface_dim_dark">#121318</color>
+ <color name="system_surface_variant_dark">#44464F</color>
+ <color name="system_on_surface_variant_dark">#C9CAD4</color>
+ <color name="system_outline_dark">#A1A2AC</color>
+ <color name="system_outline_variant_dark">#81838C</color>
+ <color name="system_error_dark">#FFBAB1</color>
+ <color name="system_on_error_dark">#370001</color>
+ <color name="system_error_container_dark">#FF5449</color>
+ <color name="system_on_error_container_dark">#000000</color>
+ <color name="system_control_activated_dark">#2F4578</color>
+ <color name="system_control_normal_dark">#C5C6D0</color>
+ <color name="system_control_highlight_dark">#FFFFFF</color>
+ <color name="system_text_primary_inverse_dark">#1A1B20</color>
+ <color name="system_text_secondary_and_tertiary_inverse_dark">#44464F</color>
+ <color name="system_text_primary_inverse_disable_only_dark">#1A1B20</color>
+ <color name="system_text_secondary_and_tertiary_inverse_disabled_dark">#1A1B20</color>
+ <color name="system_text_hint_inverse_dark">#1A1B20</color>
+ <color name="system_palette_key_color_primary_dark">#6076AC</color>
+ <color name="system_palette_key_color_secondary_dark">#70778B</color>
+ <color name="system_palette_key_color_tertiary_dark">#8C6D8C</color>
+ <color name="system_palette_key_color_neutral_dark">#76777D</color>
+ <color name="system_palette_key_color_neutral_variant_dark">#757780</color>
+ <color name="system_primary_fixed">#5E73A9</color>
+ <color name="system_primary_fixed_dim">#455B8F</color>
+ <color name="system_on_primary_fixed">#FFFFFF</color>
+ <color name="system_on_primary_fixed_variant">#FFFFFF</color>
+ <color name="system_secondary_fixed">#6E7488</color>
+ <color name="system_secondary_fixed_dim">#555C6F</color>
+ <color name="system_on_secondary_fixed">#FFFFFF</color>
+ <color name="system_on_secondary_fixed_variant">#FFFFFF</color>
+ <color name="system_tertiary_fixed">#8A6A89</color>
+ <color name="system_tertiary_fixed_dim">#705270</color>
+ <color name="system_on_tertiary_fixed">#FFFFFF</color>
+ <color name="system_on_tertiary_fixed_variant">#FFFFFF</color>
<!-- Accessibility shortcut icon background color -->
<color name="accessibility_feature_background">#5F6368</color> <!-- Google grey 700 -->
diff --git a/core/res/res/values/public-staging.xml b/core/res/res/values/public-staging.xml
index 3303c07..4be8c1b 100644
--- a/core/res/res/values/public-staging.xml
+++ b/core/res/res/values/public-staging.xml
@@ -167,6 +167,8 @@
<public name="shiftDrawingOffsetForStartOverhang" />
<!-- @FlaggedApi("android.view.flags.toolkit_set_frame_rate_read_only") -->
<public name="windowIsFrameRatePowerSavingsBalanced"/>
+ <!-- @FlaggedApi("android.service.controls.flags.Flags.FLAG_HOME_PANEL_DREAM") -->
+ <public name="dreamCategory"/>
</staging-public-group>
<staging-public-group type="id" first-id="0x01bc0000">
diff --git a/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java b/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java
index fc1fbb5..47b28899 100644
--- a/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java
+++ b/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java
@@ -28,6 +28,7 @@
import static org.mockito.AdditionalMatchers.not;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.notNull;
+import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
@@ -140,6 +141,50 @@
}
@Test
+ public void testImeRequestedVisibleAwaitingLeash() {
+ // Set null control, then request show.
+ mController.onControlsChanged(new InsetsSourceControl[] { null });
+
+ InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
+ // Request IME visible before control is available.
+ final var statsToken = ImeTracker.Token.empty();
+ mImeConsumer.onWindowFocusGained(true);
+ mController.show(WindowInsets.Type.ime(), true /* fromIme */, statsToken);
+ // Called once through the show flow.
+ verify(mController).applyAnimation(
+ eq(WindowInsets.Type.ime()), eq(true) /* show */, eq(true) /* fromIme */,
+ eq(statsToken));
+ // Clear previous invocations to verify this is never called with control without leash.
+ clearInvocations(mController);
+
+ // set control without leash and verify visibility is not applied.
+ InsetsSourceControl control = new InsetsSourceControl(ID_IME,
+ WindowInsets.Type.ime(), null /* leash */, false, new Point(), Insets.NONE);
+ mController.onControlsChanged(new InsetsSourceControl[] { control });
+ // IME show animation should not be triggered when control becomes available,
+ // as we have no leash.
+ verify(mController, never()).applyAnimation(
+ eq(WindowInsets.Type.ime()), eq(true) /* show */, eq(false) /* fromIme */,
+ and(not(eq(statsToken)), notNull()));
+ verify(mController, never()).applyAnimation(
+ eq(WindowInsets.Type.ime()), eq(false) /* show */, eq(false) /* fromIme */,
+ and(not(eq(statsToken)), notNull()));
+
+ // set control with leash and verify visibility is applied.
+ InsetsSourceControl controlWithLeash = new InsetsSourceControl(ID_IME,
+ WindowInsets.Type.ime(), mLeash, false, new Point(), Insets.NONE);
+ mController.onControlsChanged(new InsetsSourceControl[] { controlWithLeash });
+ // IME show animation should be triggered when control with leash becomes available.
+ verify(mController).applyAnimation(
+ eq(WindowInsets.Type.ime()), eq(true) /* show */, eq(false) /* fromIme */,
+ and(not(eq(statsToken)), notNull()));
+ verify(mController, never()).applyAnimation(
+ eq(WindowInsets.Type.ime()), eq(false) /* show */, eq(false) /* fromIme */,
+ and(not(eq(statsToken)), notNull()));
+ });
+ }
+
+ @Test
public void testImeGetAndClearSkipAnimationOnce_expectSkip() {
// Expect IME animation will skipped when the IME is visible at first place.
verifyImeGetAndClearSkipAnimationOnce(true /* hasWindowFocus */, true /* hasViewFocus */,
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/DividerPresenter.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/DividerPresenter.java
new file mode 100644
index 0000000..100185b
--- /dev/null
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/DividerPresenter.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 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.
+ */
+
+package androidx.window.extensions.embedding;
+
+import static android.util.TypedValue.COMPLEX_UNIT_DIP;
+
+import static androidx.window.extensions.embedding.DividerAttributes.RATIO_UNSET;
+import static androidx.window.extensions.embedding.DividerAttributes.WIDTH_UNSET;
+import static androidx.window.extensions.embedding.SplitPresenter.CONTAINER_POSITION_BOTTOM;
+import static androidx.window.extensions.embedding.SplitPresenter.CONTAINER_POSITION_LEFT;
+import static androidx.window.extensions.embedding.SplitPresenter.CONTAINER_POSITION_RIGHT;
+import static androidx.window.extensions.embedding.SplitPresenter.CONTAINER_POSITION_TOP;
+
+import android.annotation.Nullable;
+import android.app.ActivityThread;
+import android.content.Context;
+import android.util.TypedValue;
+
+import androidx.annotation.NonNull;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.window.flags.Flags;
+
+/**
+ * Manages the rendering and interaction of the divider.
+ */
+class DividerPresenter {
+ // TODO(b/327067596) Update based on UX guidance.
+ @VisibleForTesting static final float DEFAULT_MIN_RATIO = 0.35f;
+ @VisibleForTesting static final float DEFAULT_MAX_RATIO = 0.65f;
+ @VisibleForTesting static final int DEFAULT_DIVIDER_WIDTH_DP = 24;
+
+ static int getDividerWidthPx(@NonNull DividerAttributes dividerAttributes) {
+ int dividerWidthDp = dividerAttributes.getWidthDp();
+
+ // TODO(b/329193115) support divider on secondary display
+ final Context applicationContext = ActivityThread.currentActivityThread().getApplication();
+
+ return (int) TypedValue.applyDimension(
+ COMPLEX_UNIT_DIP,
+ dividerWidthDp,
+ applicationContext.getResources().getDisplayMetrics());
+ }
+
+ /**
+ * Returns the container bound offset that is a result of the presence of a divider.
+ *
+ * The offset is the relative position change for the container edge that is next to the divider
+ * due to the presence of the divider. The value could be negative or positive depending on the
+ * container position. Positive values indicate that the edge is shifting towards the right
+ * (or bottom) and negative values indicate that the edge is shifting towards the left (or top).
+ *
+ * @param splitAttributes the {@link SplitAttributes} of the split container that we want to
+ * compute bounds offset.
+ * @param position the position of the container in the split that we want to compute
+ * bounds offset for.
+ * @return the bounds offset in pixels.
+ */
+ static int getBoundsOffsetForDivider(
+ @NonNull SplitAttributes splitAttributes,
+ @SplitPresenter.ContainerPosition int position) {
+ if (!Flags.activityEmbeddingInteractiveDividerFlag()) {
+ return 0;
+ }
+ final DividerAttributes dividerAttributes = splitAttributes.getDividerAttributes();
+ if (dividerAttributes == null) {
+ return 0;
+ }
+ final int dividerWidthPx = getDividerWidthPx(dividerAttributes);
+ return getBoundsOffsetForDivider(
+ dividerWidthPx,
+ splitAttributes.getSplitType(),
+ position);
+ }
+
+ @VisibleForTesting
+ static int getBoundsOffsetForDivider(
+ int dividerWidthPx,
+ @NonNull SplitAttributes.SplitType splitType,
+ @SplitPresenter.ContainerPosition int position) {
+ if (splitType instanceof SplitAttributes.SplitType.ExpandContainersSplitType) {
+ // No divider is needed for the ExpandContainersSplitType.
+ return 0;
+ }
+ int primaryOffset;
+ if (splitType instanceof final SplitAttributes.SplitType.RatioSplitType splitRatio) {
+ // When a divider is present, both containers shrink by an amount proportional to their
+ // split ratio and sum to the width of the divider, so that the ending sizing of the
+ // containers still maintain the same ratio.
+ primaryOffset = (int) (dividerWidthPx * splitRatio.getRatio());
+ } else {
+ // Hinge split type (and other future split types) will have the divider width equally
+ // distributed to both containers.
+ primaryOffset = dividerWidthPx / 2;
+ }
+ final int secondaryOffset = dividerWidthPx - primaryOffset;
+ switch (position) {
+ case CONTAINER_POSITION_LEFT:
+ case CONTAINER_POSITION_TOP:
+ return -primaryOffset;
+ case CONTAINER_POSITION_RIGHT:
+ case CONTAINER_POSITION_BOTTOM:
+ return secondaryOffset;
+ default:
+ throw new IllegalArgumentException("Unknown position:" + position);
+ }
+ }
+
+ /**
+ * Sanitizes and sets default values in the {@link DividerAttributes}.
+ *
+ * Unset values will be set with system default values. See
+ * {@link DividerAttributes#WIDTH_UNSET} and {@link DividerAttributes#RATIO_UNSET}.
+ *
+ * @param dividerAttributes input {@link DividerAttributes}
+ * @return a {@link DividerAttributes} that has all values properly set.
+ */
+ @Nullable
+ static DividerAttributes sanitizeDividerAttributes(
+ @Nullable DividerAttributes dividerAttributes) {
+ if (dividerAttributes == null) {
+ return null;
+ }
+ int widthDp = dividerAttributes.getWidthDp();
+ if (widthDp == WIDTH_UNSET) {
+ widthDp = DEFAULT_DIVIDER_WIDTH_DP;
+ }
+
+ float minRatio = dividerAttributes.getPrimaryMinRatio();
+ if (minRatio == RATIO_UNSET) {
+ minRatio = DEFAULT_MIN_RATIO;
+ }
+
+ float maxRatio = dividerAttributes.getPrimaryMaxRatio();
+ if (maxRatio == RATIO_UNSET) {
+ maxRatio = DEFAULT_MAX_RATIO;
+ }
+
+ return new DividerAttributes.Builder(dividerAttributes)
+ .setWidthDp(widthDp)
+ .setPrimaryMinRatio(minRatio)
+ .setPrimaryMaxRatio(maxRatio)
+ .build();
+ }
+}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
index b53b9c5..f680694 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
@@ -18,6 +18,7 @@
import static android.content.pm.PackageManager.MATCH_ALL;
+import static androidx.window.extensions.embedding.DividerPresenter.getBoundsOffsetForDivider;
import static androidx.window.extensions.embedding.WindowAttributes.DIM_AREA_ON_TASK;
import android.app.Activity;
@@ -85,10 +86,10 @@
})
private @interface Position {}
- private static final int CONTAINER_POSITION_LEFT = 0;
- private static final int CONTAINER_POSITION_TOP = 1;
- private static final int CONTAINER_POSITION_RIGHT = 2;
- private static final int CONTAINER_POSITION_BOTTOM = 3;
+ static final int CONTAINER_POSITION_LEFT = 0;
+ static final int CONTAINER_POSITION_TOP = 1;
+ static final int CONTAINER_POSITION_RIGHT = 2;
+ static final int CONTAINER_POSITION_BOTTOM = 3;
@IntDef(value = {
CONTAINER_POSITION_LEFT,
@@ -96,7 +97,7 @@
CONTAINER_POSITION_RIGHT,
CONTAINER_POSITION_BOTTOM,
})
- private @interface ContainerPosition {}
+ @interface ContainerPosition {}
/**
* Result of {@link #expandSplitContainerIfNeeded(WindowContainerTransaction, SplitContainer,
@@ -738,6 +739,15 @@
private SplitAttributes sanitizeSplitAttributes(@NonNull TaskProperties taskProperties,
@NonNull SplitAttributes splitAttributes,
@Nullable Pair<Size, Size> minDimensionsPair) {
+ // Sanitize the DividerAttributes and set default values.
+ if (splitAttributes.getDividerAttributes() != null) {
+ splitAttributes = new SplitAttributes.Builder(splitAttributes)
+ .setDividerAttributes(
+ DividerPresenter.sanitizeDividerAttributes(
+ splitAttributes.getDividerAttributes())
+ ).build();
+ }
+
if (minDimensionsPair == null) {
return splitAttributes;
}
@@ -930,18 +940,18 @@
*/
private static SplitAttributes updateSplitAttributesType(
@NonNull SplitAttributes splitAttributes, @NonNull SplitType splitTypeToUpdate) {
- return new SplitAttributes.Builder()
+ return new SplitAttributes.Builder(splitAttributes)
.setSplitType(splitTypeToUpdate)
- .setLayoutDirection(splitAttributes.getLayoutDirection())
- .setAnimationBackground(splitAttributes.getAnimationBackground())
.build();
}
@NonNull
private Rect getLeftContainerBounds(@NonNull Configuration taskConfiguration,
@NonNull SplitAttributes splitAttributes, @Nullable FoldingFeature foldingFeature) {
+ final int dividerOffset = getBoundsOffsetForDivider(
+ splitAttributes, CONTAINER_POSITION_LEFT);
final int right = computeBoundaryBetweenContainers(taskConfiguration, splitAttributes,
- CONTAINER_POSITION_LEFT, foldingFeature);
+ CONTAINER_POSITION_LEFT, foldingFeature) + dividerOffset;
final Rect taskBounds = taskConfiguration.windowConfiguration.getBounds();
return new Rect(taskBounds.left, taskBounds.top, right, taskBounds.bottom);
}
@@ -949,8 +959,10 @@
@NonNull
private Rect getRightContainerBounds(@NonNull Configuration taskConfiguration,
@NonNull SplitAttributes splitAttributes, @Nullable FoldingFeature foldingFeature) {
+ final int dividerOffset = getBoundsOffsetForDivider(
+ splitAttributes, CONTAINER_POSITION_RIGHT);
final int left = computeBoundaryBetweenContainers(taskConfiguration, splitAttributes,
- CONTAINER_POSITION_RIGHT, foldingFeature);
+ CONTAINER_POSITION_RIGHT, foldingFeature) + dividerOffset;
final Rect parentBounds = taskConfiguration.windowConfiguration.getBounds();
return new Rect(left, parentBounds.top, parentBounds.right, parentBounds.bottom);
}
@@ -958,8 +970,10 @@
@NonNull
private Rect getTopContainerBounds(@NonNull Configuration taskConfiguration,
@NonNull SplitAttributes splitAttributes, @Nullable FoldingFeature foldingFeature) {
+ final int dividerOffset = getBoundsOffsetForDivider(
+ splitAttributes, CONTAINER_POSITION_TOP);
final int bottom = computeBoundaryBetweenContainers(taskConfiguration, splitAttributes,
- CONTAINER_POSITION_TOP, foldingFeature);
+ CONTAINER_POSITION_TOP, foldingFeature) + dividerOffset;
final Rect parentBounds = taskConfiguration.windowConfiguration.getBounds();
return new Rect(parentBounds.left, parentBounds.top, parentBounds.right, bottom);
}
@@ -967,8 +981,10 @@
@NonNull
private Rect getBottomContainerBounds(@NonNull Configuration taskConfiguration,
@NonNull SplitAttributes splitAttributes, @Nullable FoldingFeature foldingFeature) {
+ final int dividerOffset = getBoundsOffsetForDivider(
+ splitAttributes, CONTAINER_POSITION_BOTTOM);
final int top = computeBoundaryBetweenContainers(taskConfiguration, splitAttributes,
- CONTAINER_POSITION_BOTTOM, foldingFeature);
+ CONTAINER_POSITION_BOTTOM, foldingFeature) + dividerOffset;
final Rect parentBounds = taskConfiguration.windowConfiguration.getBounds();
return new Rect(parentBounds.left, top, parentBounds.right, parentBounds.bottom);
}
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/DividerPresenterTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/DividerPresenterTest.java
new file mode 100644
index 0000000..2a277f4
--- /dev/null
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/DividerPresenterTest.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 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.
+ */
+
+package androidx.window.extensions.embedding;
+
+import static androidx.window.extensions.embedding.DividerPresenter.getBoundsOffsetForDivider;
+import static androidx.window.extensions.embedding.SplitPresenter.CONTAINER_POSITION_BOTTOM;
+import static androidx.window.extensions.embedding.SplitPresenter.CONTAINER_POSITION_LEFT;
+import static androidx.window.extensions.embedding.SplitPresenter.CONTAINER_POSITION_RIGHT;
+import static androidx.window.extensions.embedding.SplitPresenter.CONTAINER_POSITION_TOP;
+
+import static org.junit.Assert.assertEquals;
+
+import android.platform.test.annotations.Presubmit;
+
+import androidx.annotation.NonNull;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test class for {@link DividerPresenter}.
+ *
+ * Build/Install/Run:
+ * atest WMJetpackUnitTests:DividerPresenterTest
+ */
+@Presubmit
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class DividerPresenterTest {
+ @Test
+ public void testSanitizeDividerAttributes_setDefaultValues() {
+ DividerAttributes attributes =
+ new DividerAttributes.Builder(DividerAttributes.DIVIDER_TYPE_DRAGGABLE).build();
+ DividerAttributes sanitized = DividerPresenter.sanitizeDividerAttributes(attributes);
+
+ assertEquals(DividerAttributes.DIVIDER_TYPE_DRAGGABLE, sanitized.getDividerType());
+ assertEquals(DividerPresenter.DEFAULT_DIVIDER_WIDTH_DP, sanitized.getWidthDp());
+ assertEquals(DividerPresenter.DEFAULT_MIN_RATIO, sanitized.getPrimaryMinRatio(),
+ 0.0f /* delta */);
+ assertEquals(DividerPresenter.DEFAULT_MAX_RATIO, sanitized.getPrimaryMaxRatio(),
+ 0.0f /* delta */);
+ }
+
+ @Test
+ public void testSanitizeDividerAttributes_notChangingValidValues() {
+ DividerAttributes attributes =
+ new DividerAttributes.Builder(DividerAttributes.DIVIDER_TYPE_DRAGGABLE)
+ .setWidthDp(10)
+ .setPrimaryMinRatio(0.3f)
+ .setPrimaryMaxRatio(0.7f)
+ .build();
+ DividerAttributes sanitized = DividerPresenter.sanitizeDividerAttributes(attributes);
+
+ assertEquals(attributes, sanitized);
+ }
+
+ @Test
+ public void testGetBoundsOffsetForDivider_ratioSplitType() {
+ final int dividerWidthPx = 100;
+ final float splitRatio = 0.25f;
+ final SplitAttributes.SplitType splitType =
+ new SplitAttributes.SplitType.RatioSplitType(splitRatio);
+ final int expectedTopLeftOffset = 25;
+ final int expectedBottomRightOffset = 75;
+
+ assertDividerOffsetEquals(
+ dividerWidthPx, splitType, expectedTopLeftOffset, expectedBottomRightOffset);
+ }
+
+ @Test
+ public void testGetBoundsOffsetForDivider_ratioSplitType_withRounding() {
+ final int dividerWidthPx = 101;
+ final float splitRatio = 0.25f;
+ final SplitAttributes.SplitType splitType =
+ new SplitAttributes.SplitType.RatioSplitType(splitRatio);
+ final int expectedTopLeftOffset = 25;
+ final int expectedBottomRightOffset = 76;
+
+ assertDividerOffsetEquals(
+ dividerWidthPx, splitType, expectedTopLeftOffset, expectedBottomRightOffset);
+ }
+
+ @Test
+ public void testGetBoundsOffsetForDivider_hingeSplitType() {
+ final int dividerWidthPx = 100;
+ final SplitAttributes.SplitType splitType =
+ new SplitAttributes.SplitType.HingeSplitType(
+ new SplitAttributes.SplitType.RatioSplitType(0.5f));
+
+ final int expectedTopLeftOffset = 50;
+ final int expectedBottomRightOffset = 50;
+
+ assertDividerOffsetEquals(
+ dividerWidthPx, splitType, expectedTopLeftOffset, expectedBottomRightOffset);
+ }
+
+ @Test
+ public void testGetBoundsOffsetForDivider_expandContainersSplitType() {
+ final int dividerWidthPx = 100;
+ final SplitAttributes.SplitType splitType =
+ new SplitAttributes.SplitType.ExpandContainersSplitType();
+ // Always return 0 for ExpandContainersSplitType as divider is not needed.
+ final int expectedTopLeftOffset = 0;
+ final int expectedBottomRightOffset = 0;
+
+ assertDividerOffsetEquals(
+ dividerWidthPx, splitType, expectedTopLeftOffset, expectedBottomRightOffset);
+ }
+
+ private void assertDividerOffsetEquals(
+ int dividerWidthPx,
+ @NonNull SplitAttributes.SplitType splitType,
+ int expectedTopLeftOffset,
+ int expectedBottomRightOffset) {
+ int offset = getBoundsOffsetForDivider(
+ dividerWidthPx,
+ splitType,
+ CONTAINER_POSITION_LEFT
+ );
+ assertEquals(-expectedTopLeftOffset, offset);
+
+ offset = getBoundsOffsetForDivider(
+ dividerWidthPx,
+ splitType,
+ CONTAINER_POSITION_RIGHT
+ );
+ assertEquals(expectedBottomRightOffset, offset);
+
+ offset = getBoundsOffsetForDivider(
+ dividerWidthPx,
+ splitType,
+ CONTAINER_POSITION_TOP
+ );
+ assertEquals(-expectedTopLeftOffset, offset);
+
+ offset = getBoundsOffsetForDivider(
+ dividerWidthPx,
+ splitType,
+ CONTAINER_POSITION_BOTTOM
+ );
+ assertEquals(expectedBottomRightOffset, offset);
+ }
+}
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java
index bdeeb73..cdb37ac 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java
@@ -294,7 +294,10 @@
doReturn(tf).when(splitContainer).getPrimaryContainer();
doReturn(tf).when(splitContainer).getSecondaryContainer();
doReturn(createTestTaskContainer()).when(splitContainer).getTaskContainer();
- doReturn(createSplitRule(mActivity, mActivity)).when(splitContainer).getSplitRule();
+ final SplitRule splitRule = createSplitRule(mActivity, mActivity);
+ doReturn(splitRule).when(splitContainer).getSplitRule();
+ doReturn(splitRule.getDefaultSplitAttributes())
+ .when(splitContainer).getDefaultSplitAttributes();
taskContainer = mSplitController.getTaskContainer(TASK_ID);
taskContainer.addSplitContainer(splitContainer);
// Add a mock SplitContainer on top of splitContainer
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
index ccd0b2d..d83e6b6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
@@ -496,6 +496,7 @@
if (mode == TRANSIT_TO_FRONT) {
// When the window is moved to front, make sure the crop is updated to prevent it
// from using the old crop.
+ t.setPosition(leash, change.getEndRelOffset().x, change.getEndRelOffset().y);
t.setWindowCrop(leash, change.getEndAbsBounds().width(),
change.getEndAbsBounds().height());
}
@@ -507,6 +508,10 @@
t.setMatrix(leash, 1, 0, 0, 1);
t.setAlpha(leash, 1.f);
t.setPosition(leash, change.getEndRelOffset().x, change.getEndRelOffset().y);
+ t.setWindowCrop(leash, change.getEndAbsBounds().width(),
+ change.getEndAbsBounds().height());
+ } else {
+ t.hide(leash);
}
continue;
}
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index 33830f1..014b841 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -547,6 +547,7 @@
"hwui/MinikinUtils.cpp",
"hwui/PaintImpl.cpp",
"hwui/Typeface.cpp",
+ "thread/CommonPool.cpp",
"utils/Blur.cpp",
"utils/Color.cpp",
"utils/LinearAllocator.cpp",
@@ -623,7 +624,6 @@
"renderthread/RenderThread.cpp",
"renderthread/HintSessionWrapper.cpp",
"service/GraphicsStatsService.cpp",
- "thread/CommonPool.cpp",
"utils/GLUtils.cpp",
"utils/NdkUtils.cpp",
"AutoBackendTextureRelease.cpp",
diff --git a/libs/hwui/platform/android/thread/CommonPoolBase.h b/libs/hwui/platform/android/thread/CommonPoolBase.h
new file mode 100644
index 0000000..8f836b6
--- /dev/null
+++ b/libs/hwui/platform/android/thread/CommonPoolBase.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 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.
+ */
+
+#ifndef FRAMEWORKS_BASE_COMMONPOOLBASE_H
+#define FRAMEWORKS_BASE_COMMONPOOLBASE_H
+
+#include <sys/resource.h>
+
+#include "renderthread/RenderThread.h"
+
+namespace android {
+namespace uirenderer {
+
+class CommonPoolBase {
+ PREVENT_COPY_AND_ASSIGN(CommonPoolBase);
+
+protected:
+ CommonPoolBase() {}
+
+ void setupThread(int i, std::mutex& mLock, std::vector<int>& tids,
+ std::vector<std::condition_variable>& tidConditionVars) {
+ std::array<char, 20> name{"hwuiTask"};
+ snprintf(name.data(), name.size(), "hwuiTask%d", i);
+ auto self = pthread_self();
+ pthread_setname_np(self, name.data());
+ {
+ std::unique_lock lock(mLock);
+ tids[i] = pthread_gettid_np(self);
+ tidConditionVars[i].notify_one();
+ }
+ setpriority(PRIO_PROCESS, 0, PRIORITY_FOREGROUND);
+ auto startHook = renderthread::RenderThread::getOnStartHook();
+ if (startHook) {
+ startHook(name.data());
+ }
+ }
+
+ bool supportsTid() { return true; }
+};
+
+} // namespace uirenderer
+} // namespace android
+
+#endif // FRAMEWORKS_BASE_COMMONPOOLBASE_H
diff --git a/libs/hwui/platform/host/thread/CommonPoolBase.h b/libs/hwui/platform/host/thread/CommonPoolBase.h
new file mode 100644
index 0000000..cd09101
--- /dev/null
+++ b/libs/hwui/platform/host/thread/CommonPoolBase.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 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.
+ */
+
+#ifndef FRAMEWORKS_BASE_COMMONPOOLBASE_H
+#define FRAMEWORKS_BASE_COMMONPOOLBASE_H
+
+#include <condition_variable>
+#include <mutex>
+#include <vector>
+
+#include "renderthread/RenderThread.h"
+
+namespace android {
+namespace uirenderer {
+
+class CommonPoolBase {
+ PREVENT_COPY_AND_ASSIGN(CommonPoolBase);
+
+protected:
+ CommonPoolBase() {}
+
+ void setupThread(int i, std::mutex& mLock, std::vector<int>& tids,
+ std::vector<std::condition_variable>& tidConditionVars) {
+ std::array<char, 20> name{"hwuiTask"};
+ snprintf(name.data(), name.size(), "hwuiTask%d", i);
+ {
+ std::unique_lock lock(mLock);
+ tids[i] = -1;
+ tidConditionVars[i].notify_one();
+ }
+ auto startHook = renderthread::RenderThread::getOnStartHook();
+ if (startHook) {
+ startHook(name.data());
+ }
+ }
+
+ bool supportsTid() { return false; }
+};
+
+} // namespace uirenderer
+} // namespace android
+
+#endif // FRAMEWORKS_BASE_COMMONPOOLBASE_H
diff --git a/libs/hwui/thread/CommonPool.cpp b/libs/hwui/thread/CommonPool.cpp
index dc92f9f..6c0c30f 100644
--- a/libs/hwui/thread/CommonPool.cpp
+++ b/libs/hwui/thread/CommonPool.cpp
@@ -16,16 +16,14 @@
#include "CommonPool.h"
-#include <sys/resource.h>
#include <utils/Trace.h>
-#include "renderthread/RenderThread.h"
#include <array>
namespace android {
namespace uirenderer {
-CommonPool::CommonPool() {
+CommonPool::CommonPool() : CommonPoolBase() {
ATRACE_CALL();
CommonPool* pool = this;
@@ -36,22 +34,7 @@
// Create 2 workers
for (int i = 0; i < THREAD_COUNT; i++) {
std::thread worker([pool, i, &mLock, &tids, &tidConditionVars] {
- {
- std::array<char, 20> name{"hwuiTask"};
- snprintf(name.data(), name.size(), "hwuiTask%d", i);
- auto self = pthread_self();
- pthread_setname_np(self, name.data());
- {
- std::unique_lock lock(mLock);
- tids[i] = pthread_gettid_np(self);
- tidConditionVars[i].notify_one();
- }
- setpriority(PRIO_PROCESS, 0, PRIORITY_FOREGROUND);
- auto startHook = renderthread::RenderThread::getOnStartHook();
- if (startHook) {
- startHook(name.data());
- }
- }
+ pool->setupThread(i, mLock, tids, tidConditionVars);
pool->workerLoop();
});
worker.detach();
@@ -64,7 +47,9 @@
}
}
}
- mWorkerThreadIds = std::move(tids);
+ if (pool->supportsTid()) {
+ mWorkerThreadIds = std::move(tids);
+ }
}
CommonPool& CommonPool::instance() {
@@ -95,7 +80,7 @@
void CommonPool::workerLoop() {
std::unique_lock lock(mLock);
- while (true) {
+ while (!mIsStopping) {
if (!mWorkQueue.hasWork()) {
mWaitingThreads++;
mCondition.wait(lock);
diff --git a/libs/hwui/thread/CommonPool.h b/libs/hwui/thread/CommonPool.h
index 74f852b..0c025b4 100644
--- a/libs/hwui/thread/CommonPool.h
+++ b/libs/hwui/thread/CommonPool.h
@@ -17,8 +17,6 @@
#ifndef FRAMEWORKS_BASE_COMMONPOOL_H
#define FRAMEWORKS_BASE_COMMONPOOL_H
-#include "utils/Macros.h"
-
#include <log/log.h>
#include <condition_variable>
@@ -27,6 +25,9 @@
#include <mutex>
#include <vector>
+#include "thread/CommonPoolBase.h"
+#include "utils/Macros.h"
+
namespace android {
namespace uirenderer {
@@ -73,7 +74,7 @@
int mTail = 0;
};
-class CommonPool {
+class CommonPool : private CommonPoolBase {
PREVENT_COPY_AND_ASSIGN(CommonPool);
public:
@@ -107,7 +108,10 @@
static CommonPool& instance();
CommonPool();
- ~CommonPool() {}
+ ~CommonPool() {
+ mIsStopping = true;
+ mCondition.notify_all();
+ }
void enqueue(Task&&);
void doWaitForIdle();
@@ -120,6 +124,7 @@
std::condition_variable mCondition;
int mWaitingThreads = 0;
ArrayQueue<Task, QUEUE_SIZE> mWorkQueue;
+ std::atomic_bool mIsStopping = false;
};
} // namespace uirenderer
diff --git a/packages/CrashRecovery/services/java/com/android/server/RescueParty.java b/packages/CrashRecovery/services/java/com/android/server/RescueParty.java
index d0fee44..7bdc1a0 100644
--- a/packages/CrashRecovery/services/java/com/android/server/RescueParty.java
+++ b/packages/CrashRecovery/services/java/com/android/server/RescueParty.java
@@ -163,10 +163,8 @@
* Check if we're currently attempting to reboot for a factory reset. This method must
* return true if RescueParty tries to reboot early during a boot loop, since the device
* will not be fully booted at this time.
- *
- * TODO(gavincorkery): Rename method since its scope has expanded.
*/
- public static boolean isAttemptingFactoryReset() {
+ public static boolean isRecoveryTriggeredReboot() {
return isFactoryResetPropertySet() || isRebootPropertySet();
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java b/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java
index a617bf3..fa27db9 100644
--- a/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java
+++ b/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java
@@ -60,6 +60,7 @@
public CharSequence description;
public Drawable previewImage;
public boolean supportsComplications = false;
+ public int dreamCategory;
@Override
public String toString() {
@@ -207,6 +208,7 @@
dreamInfo.settingsComponentName = dreamMetadata.settingsActivity;
dreamInfo.previewImage = dreamMetadata.previewImage;
dreamInfo.supportsComplications = dreamMetadata.showComplications;
+ dreamInfo.dreamCategory = dreamMetadata.dreamCategory;
}
dreamInfos.add(dreamInfo);
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/volume/data/repository/AudioRepository.kt b/packages/SettingsLib/src/com/android/settingslib/volume/data/repository/AudioRepository.kt
index 21cc9a8..6730aad 100644
--- a/packages/SettingsLib/src/com/android/settingslib/volume/data/repository/AudioRepository.kt
+++ b/packages/SettingsLib/src/com/android/settingslib/volume/data/repository/AudioRepository.kt
@@ -34,6 +34,7 @@
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.callbackFlow
+import kotlinx.coroutines.flow.conflate
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.filterIsInstance
import kotlinx.coroutines.flow.filterNotNull
@@ -134,6 +135,7 @@
}
.map { getCurrentAudioStream(audioStream) }
.onStart { emit(getCurrentAudioStream(audioStream)) }
+ .conflate()
.flowOn(backgroundCoroutineContext)
}
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/PlatformSlider.kt b/packages/SystemUI/compose/core/src/com/android/compose/PlatformSlider.kt
index f779cf36..596a297 100644
--- a/packages/SystemUI/compose/core/src/com/android/compose/PlatformSlider.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/PlatformSlider.kt
@@ -241,6 +241,7 @@
measurePolicy =
TrackMeasurePolicy(
sliderState = sliderState,
+ enabled = enabled,
thumbSize = LocalDensity.current.run { thumbSize.roundToPx() },
isRtl = isRtl,
onDrawingStateMeasured = { drawingState = it }
@@ -304,6 +305,7 @@
/** Measures track components sizes and calls [onDrawingStateMeasured] when it's done. */
private class TrackMeasurePolicy(
private val sliderState: SliderState,
+ private val enabled: Boolean,
private val thumbSize: Int,
private val isRtl: Boolean,
private val onDrawingStateMeasured: (DrawingState) -> Unit,
@@ -334,7 +336,7 @@
)
val iconSize = iconPlaceable?.width ?: 0
- val labelMaxWidth = (desiredWidth - iconSize) / 2
+ val labelMaxWidth = if (enabled) (desiredWidth - iconSize) / 2 else desiredWidth - iconSize
val labelPlaceable: Placeable? =
measurables
.fastFirstOrNull { it.layoutId == TrackComponent.Label }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSlider.kt b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSlider.kt
index 761292b..2435170 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSlider.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSlider.kt
@@ -16,11 +16,7 @@
package com.android.systemui.volume.panel.component.volume.ui.composable
-import androidx.compose.animation.AnimatedVisibility
-import androidx.compose.animation.animateContentSize
import androidx.compose.animation.core.animateFloatAsState
-import androidx.compose.animation.slideInVertically
-import androidx.compose.animation.slideOutVertically
import androidx.compose.foundation.basicMarquee
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.size
@@ -107,7 +103,7 @@
},
colors = sliderColors,
label = {
- Column(modifier = Modifier.animateContentSize()) {
+ Column(modifier = Modifier) {
Text(
modifier = Modifier.basicMarquee(),
text = state.label,
@@ -116,12 +112,8 @@
maxLines = 1,
)
- state.disabledMessage?.let { message ->
- AnimatedVisibility(
- !state.isEnabled,
- enter = slideInVertically { it },
- exit = slideOutVertically { it },
- ) {
+ if (!state.isEnabled) {
+ state.disabledMessage?.let { message ->
Text(
modifier = Modifier.basicMarquee(),
text = message,
diff --git a/packages/SystemUI/monet/Android.bp b/packages/SystemUI/monet/Android.bp
index 98f7ace..c54fdab 100644
--- a/packages/SystemUI/monet/Android.bp
+++ b/packages/SystemUI/monet/Android.bp
@@ -24,6 +24,7 @@
static_libs: [
"androidx.annotation_annotation",
"androidx.core_core",
+ "libmonet",
],
srcs: [
"src/**/*.java",
diff --git a/packages/SystemUI/monet/src/com/android/systemui/monet/ColorScheme.kt b/packages/SystemUI/monet/src/com/android/systemui/monet/ColorScheme.kt
index 46a90f6..47a00f4 100644
--- a/packages/SystemUI/monet/src/com/android/systemui/monet/ColorScheme.kt
+++ b/packages/SystemUI/monet/src/com/android/systemui/monet/ColorScheme.kt
@@ -20,11 +20,17 @@
import android.app.WallpaperColors
import android.graphics.Color
import com.android.internal.graphics.ColorUtils
-import com.android.internal.graphics.cam.Cam
-import com.android.internal.graphics.cam.CamUtils
+import com.google.ux.material.libmonet.hct.Hct
+import com.google.ux.material.libmonet.scheme.DynamicScheme
+import com.google.ux.material.libmonet.scheme.SchemeContent
+import com.google.ux.material.libmonet.scheme.SchemeExpressive
+import com.google.ux.material.libmonet.scheme.SchemeFruitSalad
+import com.google.ux.material.libmonet.scheme.SchemeMonochrome
+import com.google.ux.material.libmonet.scheme.SchemeNeutral
+import com.google.ux.material.libmonet.scheme.SchemeRainbow
+import com.google.ux.material.libmonet.scheme.SchemeTonalSpot
+import com.google.ux.material.libmonet.scheme.SchemeVibrant
import kotlin.math.absoluteValue
-import kotlin.math.max
-import kotlin.math.min
import kotlin.math.roundToInt
const val TAG = "ColorScheme"
@@ -33,347 +39,65 @@
const val GOOGLE_BLUE = 0xFF1b6ef3.toInt()
const val MIN_CHROMA = 5
-internal interface Hue {
- fun get(sourceColor: Cam): Double
-
- /**
- * Given a hue, and a mapping of hues to hue rotations, find which hues in the mapping the hue
- * fall betweens, and use the hue rotation of the lower hue.
- *
- * @param sourceHue hue of source color
- * @param hueAndRotations list of pairs, where the first item in a pair is a hue, and the second
- * item in the pair is a hue rotation that should be applied
- */
- fun getHueRotation(sourceHue: Float, hueAndRotations: List<Pair<Int, Int>>): Double {
- val sanitizedSourceHue = (if (sourceHue < 0 || sourceHue >= 360) 0 else sourceHue).toFloat()
- for (i in 0..hueAndRotations.size - 2) {
- val thisHue = hueAndRotations[i].first.toFloat()
- val nextHue = hueAndRotations[i + 1].first.toFloat()
- if (thisHue <= sanitizedSourceHue && sanitizedSourceHue < nextHue) {
- return ColorScheme.wrapDegreesDouble(
- sanitizedSourceHue.toDouble() + hueAndRotations[i].second
- )
- }
- }
-
- // If this statement executes, something is wrong, there should have been a rotation
- // found using the arrays.
- return sourceHue.toDouble()
- }
-}
-
-internal class HueSource : Hue {
- override fun get(sourceColor: Cam): Double {
- return sourceColor.hue.toDouble()
- }
-}
-
-internal class HueAdd(val amountDegrees: Double) : Hue {
- override fun get(sourceColor: Cam): Double {
- return ColorScheme.wrapDegreesDouble(sourceColor.hue.toDouble() + amountDegrees)
- }
-}
-
-internal class HueSubtract(val amountDegrees: Double) : Hue {
- override fun get(sourceColor: Cam): Double {
- return ColorScheme.wrapDegreesDouble(sourceColor.hue.toDouble() - amountDegrees)
- }
-}
-
-internal class HueVibrantSecondary() : Hue {
- val hueToRotations =
- listOf(
- Pair(0, 18),
- Pair(41, 15),
- Pair(61, 10),
- Pair(101, 12),
- Pair(131, 15),
- Pair(181, 18),
- Pair(251, 15),
- Pair(301, 12),
- Pair(360, 12)
- )
-
- override fun get(sourceColor: Cam): Double {
- return getHueRotation(sourceColor.hue, hueToRotations)
- }
-}
-
-internal class HueVibrantTertiary() : Hue {
- val hueToRotations =
- listOf(
- Pair(0, 35),
- Pair(41, 30),
- Pair(61, 20),
- Pair(101, 25),
- Pair(131, 30),
- Pair(181, 35),
- Pair(251, 30),
- Pair(301, 25),
- Pair(360, 25)
- )
-
- override fun get(sourceColor: Cam): Double {
- return getHueRotation(sourceColor.hue, hueToRotations)
- }
-}
-
-internal class HueExpressiveSecondary() : Hue {
- val hueToRotations =
- listOf(
- Pair(0, 45),
- Pair(21, 95),
- Pair(51, 45),
- Pair(121, 20),
- Pair(151, 45),
- Pair(191, 90),
- Pair(271, 45),
- Pair(321, 45),
- Pair(360, 45)
- )
-
- override fun get(sourceColor: Cam): Double {
- return getHueRotation(sourceColor.hue, hueToRotations)
- }
-}
-
-internal class HueExpressiveTertiary() : Hue {
- val hueToRotations =
- listOf(
- Pair(0, 120),
- Pair(21, 120),
- Pair(51, 20),
- Pair(121, 45),
- Pair(151, 20),
- Pair(191, 15),
- Pair(271, 20),
- Pair(321, 120),
- Pair(360, 120)
- )
-
- override fun get(sourceColor: Cam): Double {
- return getHueRotation(sourceColor.hue, hueToRotations)
- }
-}
-
-internal interface Chroma {
- fun get(sourceColor: Cam): Double
-
- companion object {
- val MAX_VALUE = 120.0
- val MIN_VALUE = 0.0
- }
-}
-
-internal class ChromaMaxOut : Chroma {
- override fun get(sourceColor: Cam): Double {
- // Intentionally high. Gamut mapping from impossible HCT to sRGB will ensure that
- // the maximum chroma is reached, even if lower than this constant.
- return Chroma.MAX_VALUE + 10.0
- }
-}
-
-internal class ChromaMultiple(val multiple: Double) : Chroma {
- override fun get(sourceColor: Cam): Double {
- return sourceColor.chroma * multiple
- }
-}
-
-internal class ChromaAdd(val amount: Double) : Chroma {
- override fun get(sourceColor: Cam): Double {
- return sourceColor.chroma + amount
- }
-}
-
-internal class ChromaBound(
- val baseChroma: Chroma,
- val minVal: Double,
- val maxVal: Double,
-) : Chroma {
- override fun get(sourceColor: Cam): Double {
- val result = baseChroma.get(sourceColor)
- return min(max(result, minVal), maxVal)
- }
-}
-
-internal class ChromaConstant(val chroma: Double) : Chroma {
- override fun get(sourceColor: Cam): Double {
- return chroma
- }
-}
-
-internal class ChromaSource : Chroma {
- override fun get(sourceColor: Cam): Double {
- return sourceColor.chroma.toDouble()
- }
-}
-
-internal class TonalSpec(val hue: Hue = HueSource(), val chroma: Chroma) {
- fun shades(sourceColor: Cam): List<Int> {
- val hue = hue.get(sourceColor)
- val chroma = chroma.get(sourceColor)
- return Shades.of(hue.toFloat(), chroma.toFloat()).toList()
- }
-
- fun getAtTone(sourceColor: Cam, tone: Float): Int {
- val hue = hue.get(sourceColor)
- val chroma = chroma.get(sourceColor)
- return ColorUtils.CAMToColor(hue.toFloat(), chroma.toFloat(), (1000f - tone) / 10f)
- }
-}
-
-internal class CoreSpec(
- val a1: TonalSpec,
- val a2: TonalSpec,
- val a3: TonalSpec,
- val n1: TonalSpec,
- val n2: TonalSpec
-)
-
-enum class Style(internal val coreSpec: CoreSpec) {
- SPRITZ(
- CoreSpec(
- a1 = TonalSpec(HueSource(), ChromaConstant(12.0)),
- a2 = TonalSpec(HueSource(), ChromaConstant(8.0)),
- a3 = TonalSpec(HueSource(), ChromaConstant(16.0)),
- n1 = TonalSpec(HueSource(), ChromaConstant(2.0)),
- n2 = TonalSpec(HueSource(), ChromaConstant(2.0))
- )
- ),
- TONAL_SPOT(
- CoreSpec(
- a1 = TonalSpec(HueSource(), ChromaConstant(36.0)),
- a2 = TonalSpec(HueSource(), ChromaConstant(16.0)),
- a3 = TonalSpec(HueAdd(60.0), ChromaConstant(24.0)),
- n1 = TonalSpec(HueSource(), ChromaConstant(6.0)),
- n2 = TonalSpec(HueSource(), ChromaConstant(8.0))
- )
- ),
- VIBRANT(
- CoreSpec(
- a1 = TonalSpec(HueSource(), ChromaMaxOut()),
- a2 = TonalSpec(HueVibrantSecondary(), ChromaConstant(24.0)),
- a3 = TonalSpec(HueVibrantTertiary(), ChromaConstant(32.0)),
- n1 = TonalSpec(HueSource(), ChromaConstant(10.0)),
- n2 = TonalSpec(HueSource(), ChromaConstant(12.0))
- )
- ),
- EXPRESSIVE(
- CoreSpec(
- a1 = TonalSpec(HueAdd(240.0), ChromaConstant(40.0)),
- a2 = TonalSpec(HueExpressiveSecondary(), ChromaConstant(24.0)),
- a3 = TonalSpec(HueExpressiveTertiary(), ChromaConstant(32.0)),
- n1 = TonalSpec(HueAdd(15.0), ChromaConstant(8.0)),
- n2 = TonalSpec(HueAdd(15.0), ChromaConstant(12.0))
- )
- ),
- RAINBOW(
- CoreSpec(
- a1 = TonalSpec(HueSource(), ChromaConstant(48.0)),
- a2 = TonalSpec(HueSource(), ChromaConstant(16.0)),
- a3 = TonalSpec(HueAdd(60.0), ChromaConstant(24.0)),
- n1 = TonalSpec(HueSource(), ChromaConstant(0.0)),
- n2 = TonalSpec(HueSource(), ChromaConstant(0.0))
- )
- ),
- FRUIT_SALAD(
- CoreSpec(
- a1 = TonalSpec(HueSubtract(50.0), ChromaConstant(48.0)),
- a2 = TonalSpec(HueSubtract(50.0), ChromaConstant(36.0)),
- a3 = TonalSpec(HueSource(), ChromaConstant(36.0)),
- n1 = TonalSpec(HueSource(), ChromaConstant(10.0)),
- n2 = TonalSpec(HueSource(), ChromaConstant(16.0))
- )
- ),
- CONTENT(
- CoreSpec(
- a1 = TonalSpec(HueSource(), ChromaSource()),
- a2 = TonalSpec(HueSource(), ChromaMultiple(0.33)),
- a3 = TonalSpec(HueSource(), ChromaMultiple(0.66)),
- n1 = TonalSpec(HueSource(), ChromaMultiple(0.0833)),
- n2 = TonalSpec(HueSource(), ChromaMultiple(0.1666))
- )
- ),
- MONOCHROMATIC(
- CoreSpec(
- a1 = TonalSpec(HueSource(), ChromaConstant(.0)),
- a2 = TonalSpec(HueSource(), ChromaConstant(.0)),
- a3 = TonalSpec(HueSource(), ChromaConstant(.0)),
- n1 = TonalSpec(HueSource(), ChromaConstant(.0)),
- n2 = TonalSpec(HueSource(), ChromaConstant(.0))
- )
- ),
- CLOCK(
- CoreSpec(
- a1 = TonalSpec(HueSource(), ChromaBound(ChromaSource(), 20.0, Chroma.MAX_VALUE)),
- a2 = TonalSpec(HueAdd(10.0), ChromaBound(ChromaMultiple(0.85), 17.0, 40.0)),
- a3 = TonalSpec(HueAdd(20.0), ChromaBound(ChromaAdd(20.0), 50.0, Chroma.MAX_VALUE)),
-
- // Not Used
- n1 = TonalSpec(HueSource(), ChromaConstant(0.0)),
- n2 = TonalSpec(HueSource(), ChromaConstant(0.0))
- )
- ),
- CLOCK_VIBRANT(
- CoreSpec(
- a1 = TonalSpec(HueSource(), ChromaBound(ChromaSource(), 70.0, Chroma.MAX_VALUE)),
- a2 = TonalSpec(HueAdd(20.0), ChromaBound(ChromaSource(), 70.0, Chroma.MAX_VALUE)),
- a3 = TonalSpec(HueAdd(60.0), ChromaBound(ChromaSource(), 70.0, Chroma.MAX_VALUE)),
-
- // Not Used
- n1 = TonalSpec(HueSource(), ChromaConstant(0.0)),
- n2 = TonalSpec(HueSource(), ChromaConstant(0.0))
- )
- )
+enum class Style{
+ SPRITZ,
+ TONAL_SPOT,
+ VIBRANT,
+ EXPRESSIVE,
+ RAINBOW,
+ FRUIT_SALAD,
+ CONTENT,
+ MONOCHROMATIC,
+ CLOCK,
+ CLOCK_VIBRANT
}
class TonalPalette
internal constructor(
- private val spec: TonalSpec,
- seedColor: Int,
+ private val materialTonalPalette: com.google.ux.material.libmonet.palettes.TonalPalette
) {
- val seedCam: Cam = Cam.fromInt(seedColor)
- val allShades: List<Int> = spec.shades(seedCam)
- val allShadesMapped: Map<Int, Int> = SHADE_KEYS.zip(allShades).toMap()
- val baseColor: Int
+ @Deprecated("Do not use. For color system only")
+ val allShades: List<Int>
+ val allShadesMapped: Map<Int, Int>
- init {
- val h = spec.hue.get(seedCam).toFloat()
- val c = spec.chroma.get(seedCam).toFloat()
- baseColor = ColorUtils.CAMToColor(h, c, CamUtils.lstarFromInt(seedColor))
+ init{
+ allShades = SHADE_KEYS.map {key -> getAtTone(key.toFloat()) }
+ allShadesMapped = SHADE_KEYS.zip(allShades).toMap()
}
// Dynamically computed tones across the full range from 0 to 1000
- fun getAtTone(tone: Float) = spec.getAtTone(seedCam, tone)
+ fun getAtTone(shade: Float): Int = materialTonalPalette.tone(((1000.0f - shade) / 10f).toInt())
// Predefined & precomputed tones
- val s10: Int
+ val s0: Int
get() = this.allShades[0]
- val s50: Int
+ val s10: Int
get() = this.allShades[1]
- val s100: Int
+ val s50: Int
get() = this.allShades[2]
- val s200: Int
+ val s100: Int
get() = this.allShades[3]
- val s300: Int
+ val s200: Int
get() = this.allShades[4]
- val s400: Int
+ val s300: Int
get() = this.allShades[5]
- val s500: Int
+ val s400: Int
get() = this.allShades[6]
- val s600: Int
+ val s500: Int
get() = this.allShades[7]
- val s700: Int
+ val s600: Int
get() = this.allShades[8]
- val s800: Int
+ val s700: Int
get() = this.allShades[9]
- val s900: Int
+ val s800: Int
get() = this.allShades[10]
- val s1000: Int
+ val s900: Int
get() = this.allShades[11]
+ val s1000: Int
+ get() = this.allShades[12]
companion object {
- val SHADE_KEYS = listOf(10, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000)
+ val SHADE_KEYS = listOf(0, 10, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000)
}
}
@@ -381,9 +105,20 @@
"instead")
class ColorScheme(
@ColorInt val seed: Int,
- val darkTheme: Boolean,
- val style: Style = Style.TONAL_SPOT
+ val isDark: Boolean,
+ val style: Style,
+ val contrastLevel: Double
) {
+ var materialScheme: DynamicScheme
+
+ private val proposedSeedHct: Hct = Hct.fromInt(seed)
+ private val seedHct: Hct = Hct.fromInt(if (seed == Color.TRANSPARENT) {
+ GOOGLE_BLUE
+ } else if (style != Style.CONTENT && proposedSeedHct.chroma < 5) {
+ GOOGLE_BLUE
+ } else {
+ seed
+ })
val accent1: TonalPalette
val accent2: TonalPalette
@@ -395,62 +130,49 @@
@JvmOverloads
constructor(
+ @ColorInt seed: Int,
+ darkTheme: Boolean,
+ style: Style
+ ) : this(seed, darkTheme, style, 0.5)
+
+ @JvmOverloads
+ constructor(
wallpaperColors: WallpaperColors,
darkTheme: Boolean,
style: Style = Style.TONAL_SPOT
) : this(getSeedColor(wallpaperColors, style != Style.CONTENT), darkTheme, style)
- val allHues: List<TonalPalette>
- get() {
- return listOf(accent1, accent2, accent3, neutral1, neutral2)
- }
-
- val allAccentColors: List<Int>
- get() {
- val allColors = mutableListOf<Int>()
- allColors.addAll(accent1.allShades)
- allColors.addAll(accent2.allShades)
- allColors.addAll(accent3.allShades)
- return allColors
- }
-
- val allNeutralColors: List<Int>
- get() {
- val allColors = mutableListOf<Int>()
- allColors.addAll(neutral1.allShades)
- allColors.addAll(neutral2.allShades)
- return allColors
- }
-
val backgroundColor
- get() = ColorUtils.setAlphaComponent(if (darkTheme) neutral1.s700 else neutral1.s10, 0xFF)
+ get() = ColorUtils.setAlphaComponent(if (isDark) neutral1.s700 else neutral1.s10, 0xFF)
val accentColor
- get() = ColorUtils.setAlphaComponent(if (darkTheme) accent1.s100 else accent1.s500, 0xFF)
+ get() = ColorUtils.setAlphaComponent(if (isDark) accent1.s100 else accent1.s500, 0xFF)
init {
- val proposedSeedCam = Cam.fromInt(seed)
- val seedArgb =
- if (seed == Color.TRANSPARENT) {
- GOOGLE_BLUE
- } else if (style != Style.CONTENT && proposedSeedCam.chroma < 5) {
- GOOGLE_BLUE
- } else {
- seed
- }
+ materialScheme = when (style) {
+ Style.SPRITZ -> SchemeNeutral(seedHct, isDark, contrastLevel)
+ Style.TONAL_SPOT -> SchemeTonalSpot(seedHct, isDark, contrastLevel)
+ Style.VIBRANT -> SchemeVibrant(seedHct, isDark, contrastLevel)
+ Style.EXPRESSIVE -> SchemeExpressive(seedHct, isDark, contrastLevel)
+ Style.RAINBOW -> SchemeRainbow(seedHct, isDark, contrastLevel)
+ Style.FRUIT_SALAD -> SchemeFruitSalad(seedHct, isDark, contrastLevel)
+ Style.CONTENT -> SchemeContent(seedHct, isDark, contrastLevel)
+ Style.MONOCHROMATIC -> SchemeMonochrome(seedHct, isDark, contrastLevel)
- accent1 = TonalPalette(style.coreSpec.a1, seedArgb)
- accent2 = TonalPalette(style.coreSpec.a2, seedArgb)
- accent3 = TonalPalette(style.coreSpec.a3, seedArgb)
- neutral1 = TonalPalette(style.coreSpec.n1, seedArgb)
- neutral2 = TonalPalette(style.coreSpec.n2, seedArgb)
+ // SystemUI Schemes
+ Style.CLOCK -> SchemeClock(seedHct, isDark, contrastLevel)
+ Style.CLOCK_VIBRANT -> SchemeClockVibrant(seedHct, isDark, contrastLevel)
+ }
+
+ accent1 = TonalPalette(materialScheme.primaryPalette)
+ accent2 = TonalPalette(materialScheme.secondaryPalette)
+ accent3 = TonalPalette(materialScheme.tertiaryPalette)
+ neutral1 = TonalPalette(materialScheme.neutralPalette)
+ neutral2 = TonalPalette(materialScheme.neutralVariantPalette)
}
- val shadeCount
- get() = this.accent1.allShades.size
-
val seedTone: Float
- get() = 1000f - CamUtils.lstarFromInt(seed) * 10f
+ get() = 1000f - proposedSeedHct.tone.toFloat() * 10f
override fun toString(): String {
return "ColorScheme {\n" +
@@ -507,7 +229,7 @@
if (!filter) {
true
} else {
- Cam.fromInt(it).chroma >= MIN_CHROMA
+ Hct.fromInt(it).chroma >= MIN_CHROMA
}
}
.toList()
@@ -519,15 +241,15 @@
val intToProportion =
wallpaperColors.allColors.mapValues { it.value.toDouble() / totalPopulation }
- val intToCam = wallpaperColors.allColors.mapValues { Cam.fromInt(it.key) }
+ val intToHct = wallpaperColors.allColors.mapValues { Hct.fromInt(it.key) }
// Get an array with 360 slots. A slot contains the percentage of colors with that hue.
- val hueProportions = huePopulations(intToCam, intToProportion, filter)
+ val hueProportions = huePopulations(intToHct, intToProportion, filter)
// Map each color to the percentage of the image with its hue.
val intToHueProportion =
wallpaperColors.allColors.mapValues {
- val cam = intToCam[it.key]!!
- val hue = cam.hue.roundToInt()
+ val hct = intToHct[it.key]!!
+ val hue = hct.hue.roundToInt()
var proportion = 0.0
for (i in hue - 15..hue + 15) {
proportion += hueProportions[wrapDegrees(i)]
@@ -537,18 +259,18 @@
// Remove any inappropriate seed colors. For example, low chroma colors look grayscale
// raising their chroma will turn them to a much louder color that may not have been
// in the image.
- val filteredIntToCam =
- if (!filter) intToCam
+ val filteredIntToHct =
+ if (!filter) intToHct
else
- (intToCam.filter {
- val cam = it.value
+ (intToHct.filter {
+ val hct = it.value
val proportion = intToHueProportion[it.key]!!
- cam.chroma >= MIN_CHROMA &&
+ hct.chroma >= MIN_CHROMA &&
(totalPopulationMeaningless || proportion > 0.01)
})
// Sort the colors by score, from high to low.
val intToScoreIntermediate =
- filteredIntToCam.mapValues { score(it.value, intToHueProportion[it.key]!!) }
+ filteredIntToHct.mapValues { score(it.value, intToHueProportion[it.key]!!) }
val intToScore = intToScoreIntermediate.entries.toMutableList()
intToScore.sortByDescending { it.value }
@@ -564,8 +286,8 @@
val int = entry.key
val existingSeedNearby =
seeds.find {
- val hueA = intToCam[int]!!.hue
- val hueB = intToCam[it]!!.hue
+ val hueA = intToHct[int]!!.hue
+ val hueB = intToHct[it]!!.hue
hueDiff(hueA, hueB) < i
} != null
if (existingSeedNearby) {
@@ -600,30 +322,16 @@
}
}
- public fun wrapDegreesDouble(degrees: Double): Double {
- return when {
- degrees < 0 -> {
- (degrees % 360) + 360
- }
- degrees >= 360 -> {
- degrees % 360
- }
- else -> {
- degrees
- }
- }
- }
-
- private fun hueDiff(a: Float, b: Float): Float {
+ private fun hueDiff(a: Double, b: Double): Double {
return 180f - ((a - b).absoluteValue - 180f).absoluteValue
}
private fun stringForColor(color: Int): String {
val width = 4
- val hct = Cam.fromInt(color)
+ val hct = Hct.fromInt(color)
val h = "H${hct.hue.roundToInt().toString().padEnd(width)}"
val c = "C${hct.chroma.roundToInt().toString().padEnd(width)}"
- val t = "T${CamUtils.lstarFromInt(color).roundToInt().toString().padEnd(width)}"
+ val t = "T${hct.tone.roundToInt().toString().padEnd(width)}"
val hex = Integer.toHexString(color and 0xffffff).padStart(6, '0').uppercase()
return "$h$c$t = #$hex"
}
@@ -633,16 +341,16 @@
colors.map { stringForColor(it) }.joinToString(separator = "\n") { it }
}
- private fun score(cam: Cam, proportion: Double): Double {
+ private fun score(hct: Hct, proportion: Double): Double {
val proportionScore = 0.7 * 100.0 * proportion
val chromaScore =
- if (cam.chroma < ACCENT1_CHROMA) 0.1 * (cam.chroma - ACCENT1_CHROMA)
- else 0.3 * (cam.chroma - ACCENT1_CHROMA)
+ if (hct.chroma < ACCENT1_CHROMA) 0.1 * (hct.chroma - ACCENT1_CHROMA)
+ else 0.3 * (hct.chroma - ACCENT1_CHROMA)
return chromaScore + proportionScore
}
private fun huePopulations(
- camByColor: Map<Int, Cam>,
+ hctByColor: Map<Int, Hct>,
populationByColor: Map<Int, Double>,
filter: Boolean = true
): List<Double> {
@@ -650,9 +358,9 @@
for (entry in populationByColor.entries) {
val population = populationByColor[entry.key]!!
- val cam = camByColor[entry.key]!!
- val hue = cam.hue.roundToInt() % 360
- if (filter && cam.chroma <= MIN_CHROMA) {
+ val hct = hctByColor[entry.key]!!
+ val hue = hct.hue.roundToInt() % 360
+ if (filter && hct.chroma <= MIN_CHROMA) {
continue
}
huePopulation[hue] = huePopulation[hue] + population
diff --git a/packages/SystemUI/monet/src/com/android/systemui/monet/SchemeClock.java b/packages/SystemUI/monet/src/com/android/systemui/monet/SchemeClock.java
new file mode 100644
index 0000000..4747cc5
--- /dev/null
+++ b/packages/SystemUI/monet/src/com/android/systemui/monet/SchemeClock.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 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.
+ */
+
+package com.android.systemui.monet;
+
+import static com.google.ux.material.libmonet.utils.MathUtils.clampDouble;
+
+import static java.lang.Double.max;
+
+import com.google.ux.material.libmonet.hct.Hct;
+import com.google.ux.material.libmonet.palettes.TonalPalette;
+import com.google.ux.material.libmonet.scheme.DynamicScheme;
+import com.google.ux.material.libmonet.scheme.Variant;
+
+public class SchemeClock extends DynamicScheme {
+ public SchemeClock(Hct sourceColorHct, boolean isDark, double contrastLevel) {
+ super(
+ sourceColorHct,
+ Variant.MONOCHROME,
+ isDark,
+ contrastLevel,
+ /*primary*/
+ TonalPalette.fromHueAndChroma(
+ /*hue*/ sourceColorHct.getHue(),
+ /*chroma*/ max(sourceColorHct.getChroma(), 20)
+ ),
+ /*secondary*/
+ TonalPalette.fromHueAndChroma(
+ /*hue*/ sourceColorHct.getHue() + 10.0,
+ /*chroma*/ clampDouble(17, 40, sourceColorHct.getChroma() * 0.85)
+ ),
+ /*tertiary*/
+ TonalPalette.fromHueAndChroma(
+ /*hue*/ sourceColorHct.getHue() + 20.0,
+ /*chroma*/ max(sourceColorHct.getChroma() + 20, 50)
+ ),
+
+ //not used
+ TonalPalette.fromHueAndChroma(sourceColorHct.getHue(), 0.0),
+ TonalPalette.fromHueAndChroma(sourceColorHct.getHue(), 0.0));
+ }
+}
diff --git a/packages/SystemUI/monet/src/com/android/systemui/monet/SchemeClockVibrant.java b/packages/SystemUI/monet/src/com/android/systemui/monet/SchemeClockVibrant.java
new file mode 100644
index 0000000..fb5e972
--- /dev/null
+++ b/packages/SystemUI/monet/src/com/android/systemui/monet/SchemeClockVibrant.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 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.
+ */
+
+package com.android.systemui.monet;
+
+import static java.lang.Double.max;
+
+import com.google.ux.material.libmonet.hct.Hct;
+import com.google.ux.material.libmonet.palettes.TonalPalette;
+import com.google.ux.material.libmonet.scheme.DynamicScheme;
+import com.google.ux.material.libmonet.scheme.Variant;
+
+public class SchemeClockVibrant extends DynamicScheme {
+ public SchemeClockVibrant(Hct sourceColorHct, boolean isDark, double contrastLevel) {
+ super(
+ sourceColorHct,
+ Variant.MONOCHROME,
+ isDark,
+ contrastLevel,
+ /*primary*/
+ TonalPalette.fromHueAndChroma(
+ /*hue*/ sourceColorHct.getHue(),
+ /*chroma*/ max(sourceColorHct.getChroma(), 70)
+ ),
+ /*secondary*/
+ TonalPalette.fromHueAndChroma(
+ /*hue*/ sourceColorHct.getHue() + 20.0,
+ /*chroma*/ max(sourceColorHct.getChroma(), 70)
+ ),
+ /*tertiary*/
+ TonalPalette.fromHueAndChroma(
+ /*hue*/ sourceColorHct.getHue() + 60.0,
+ /*chroma*/ max(sourceColorHct.getChroma(), 70)
+ ),
+
+ //not used
+ TonalPalette.fromHueAndChroma(sourceColorHct.getHue(), 0.0),
+ TonalPalette.fromHueAndChroma(sourceColorHct.getHue(), 0.0));
+ }
+}
diff --git a/packages/SystemUI/res/xml/home_controls_dream_metadata.xml b/packages/SystemUI/res/xml/home_controls_dream_metadata.xml
index eb7c79e..69bd9a4 100644
--- a/packages/SystemUI/res/xml/home_controls_dream_metadata.xml
+++ b/packages/SystemUI/res/xml/home_controls_dream_metadata.xml
@@ -16,4 +16,5 @@
<dream xmlns:android="http://schemas.android.com/apk/res/android"
android:showClockAndComplications="false"
android:previewImage="@drawable/homecontrols_sq"
+ android:dreamCategory="home_panel"
/>
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
index b5efc44..aac18e3 100644
--- a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
+++ b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
@@ -86,15 +86,6 @@
import com.android.systemui.util.settings.SecureSettings;
import com.google.ux.material.libmonet.dynamiccolor.MaterialDynamicColors;
-import com.google.ux.material.libmonet.hct.Hct;
-import com.google.ux.material.libmonet.scheme.DynamicScheme;
-import com.google.ux.material.libmonet.scheme.SchemeExpressive;
-import com.google.ux.material.libmonet.scheme.SchemeFruitSalad;
-import com.google.ux.material.libmonet.scheme.SchemeMonochrome;
-import com.google.ux.material.libmonet.scheme.SchemeNeutral;
-import com.google.ux.material.libmonet.scheme.SchemeRainbow;
-import com.google.ux.material.libmonet.scheme.SchemeTonalSpot;
-import com.google.ux.material.libmonet.scheme.SchemeVibrant;
import org.json.JSONException;
import org.json.JSONObject;
@@ -150,7 +141,7 @@
// Dominant color extracted from wallpaper, NOT the color used on the overlay
protected int mMainWallpaperColor = Color.TRANSPARENT;
// UI contrast as reported by UiModeManager
- private float mContrast = 0;
+ private double mContrast = 0.0;
// Theme variant: Vibrant, Tonal, Expressive, etc
@VisibleForTesting
protected Style mThemeStyle = Style.TONAL_SPOT;
@@ -170,8 +161,8 @@
private final JavaAdapter mJavaAdapter;
private final KeyguardTransitionInteractor mKeyguardTransitionInteractor;
private final UiModeManager mUiModeManager;
- private DynamicScheme mDynamicSchemeDark;
- private DynamicScheme mDynamicSchemeLight;
+ private ColorScheme mDarkColorScheme;
+ private ColorScheme mLightColorScheme;
// Defers changing themes until Setup Wizard is done.
private boolean mDeferredThemeEvaluation;
@@ -210,7 +201,7 @@
boolean currentUser = userId == mUserTracker.getUserId();
boolean isAsleep = themeOverlayControllerWakefulnessDeprecation()
? mKeyguardTransitionInteractor.isFinishedInStateWhereValue(
- state -> KeyguardState.Companion.deviceIsAsleepInState(state))
+ KeyguardState.Companion::deviceIsAsleepInState)
: mWakefulnessLifecycle.getWakefulness() != WAKEFULNESS_ASLEEP;
if (currentUser && !mAcceptColorEvents && isAsleep) {
@@ -483,19 +474,14 @@
reevaluateSystemTheme(true /* forceReload */);
});
+ // All wallpaper color and keyguard logic only applies when Monet is enabled.
if (!mIsMonetEnabled) {
return;
}
mUserTracker.addCallback(mUserTrackerCallback, mMainExecutor);
-
mDeviceProvisionedController.addCallback(mDeviceProvisionedListener);
- // All wallpaper color and keyguard logic only applies when Monet is enabled.
- if (!mIsMonetEnabled) {
- return;
- }
-
// Upon boot, make sure we have the most up to date colors
Runnable updateColors = () -> {
WallpaperColors systemColor = mWallpaperManager.getWallpaperColors(
@@ -589,29 +575,6 @@
return ColorScheme.getSeedColor(wallpaperColors);
}
- private static DynamicScheme dynamicSchemeFromStyle(Style style, int color,
- boolean isDark, double contrastLevel) {
- Hct sourceColorHct = Hct.fromInt(color);
- switch (style) {
- case EXPRESSIVE:
- return new SchemeExpressive(sourceColorHct, isDark, contrastLevel);
- case SPRITZ:
- return new SchemeNeutral(sourceColorHct, isDark, contrastLevel);
- case TONAL_SPOT:
- return new SchemeTonalSpot(sourceColorHct, isDark, contrastLevel);
- case FRUIT_SALAD:
- return new SchemeFruitSalad(sourceColorHct, isDark, contrastLevel);
- case RAINBOW:
- return new SchemeRainbow(sourceColorHct, isDark, contrastLevel);
- case VIBRANT:
- return new SchemeVibrant(sourceColorHct, isDark, contrastLevel);
- case MONOCHROMATIC:
- return new SchemeMonochrome(sourceColorHct, isDark, contrastLevel);
- default:
- return null;
- }
- }
-
@VisibleForTesting
protected boolean isNightMode() {
return (mResources.getConfiguration().uiMode
@@ -626,22 +589,17 @@
@VisibleForTesting
protected boolean isPrivateProfile(UserHandle userHandle) {
Context usercontext = mContext.createContextAsUser(userHandle,0);
- if (usercontext.getSystemService(UserManager.class).isPrivateProfile()) {
- return true;
- }
- return false;
+ return usercontext.getSystemService(UserManager.class).isPrivateProfile();
}
private void createOverlays(int color) {
- boolean nightMode = isNightMode();
- mColorScheme = new ColorScheme(color, nightMode, mThemeStyle);
+ mDarkColorScheme = new ColorScheme(color, true /* isDark */, mThemeStyle, mContrast);
+ mLightColorScheme = new ColorScheme(color, false /* isDark */, mThemeStyle, mContrast);
+ mColorScheme = isNightMode() ? mDarkColorScheme : mLightColorScheme;
+
mNeutralOverlay = createNeutralOverlay();
mSecondaryOverlay = createAccentOverlay();
- mDynamicSchemeDark = dynamicSchemeFromStyle(
- mThemeStyle, color, true /* isDark */, mContrast);
- mDynamicSchemeLight = dynamicSchemeFromStyle(
- mThemeStyle, color, false /* isDark */, mContrast);
mDynamicOverlay = createDynamicOverlay();
}
@@ -682,10 +640,10 @@
private void assignDynamicPaletteToOverlay(FabricatedOverlay overlay, boolean isDark) {
String suffix = isDark ? "dark" : "light";
- DynamicScheme scheme = isDark ? mDynamicSchemeDark : mDynamicSchemeLight;
+ ColorScheme scheme = isDark ? mDarkColorScheme : mLightColorScheme;
DynamicColors.allDynamicColorsMapped(mIsFidelityEnabled).forEach(p -> {
String resourceName = "android:color/system_" + p.first + "_" + suffix;
- int colorValue = p.second.getArgb(scheme);
+ int colorValue = p.second.getArgb(scheme.getMaterialScheme());
overlay.setResourceValue(resourceName, TYPE_INT_COLOR_ARGB8, colorValue,
null /* configuration */);
});
@@ -694,7 +652,7 @@
private void assignFixedColorsToOverlay(FabricatedOverlay overlay) {
DynamicColors.getFixedColorsMapped(mIsFidelityEnabled).forEach(p -> {
String resourceName = "android:color/system_" + p.first;
- int colorValue = p.second.getArgb(mDynamicSchemeLight);
+ int colorValue = p.second.getArgb(mLightColorScheme.getMaterialScheme());
overlay.setResourceValue(resourceName, TYPE_INT_COLOR_ARGB8, colorValue,
null /* configuration */);
});
@@ -702,6 +660,7 @@
/**
* Checks if the color scheme in mColorScheme matches the current system palettes.
+ *
* @param managedProfiles List of managed profiles for this user.
*/
private boolean colorSchemeIsApplied(Set<UserHandle> managedProfiles) {
@@ -723,15 +682,18 @@
&& res.getColor(android.R.color.system_neutral2_500, theme)
== mColorScheme.getNeutral2().getS500()
&& res.getColor(android.R.color.system_outline_variant_dark, theme)
- == dynamicColors.outlineVariant().getArgb(mDynamicSchemeDark)
+ == dynamicColors.outlineVariant().getArgb(mDarkColorScheme.getMaterialScheme())
&& res.getColor(android.R.color.system_outline_variant_light, theme)
- == dynamicColors.outlineVariant().getArgb(mDynamicSchemeLight)
+ == dynamicColors.outlineVariant().getArgb(mLightColorScheme.getMaterialScheme())
&& res.getColor(android.R.color.system_primary_container_dark, theme)
- == dynamicColors.primaryContainer().getArgb(mDynamicSchemeDark)
+ == dynamicColors.primaryContainer().getArgb(
+ mDarkColorScheme.getMaterialScheme())
&& res.getColor(android.R.color.system_primary_container_light, theme)
- == dynamicColors.primaryContainer().getArgb(mDynamicSchemeLight)
+ == dynamicColors.primaryContainer().getArgb(
+ mLightColorScheme.getMaterialScheme())
&& res.getColor(android.R.color.system_primary_fixed, theme)
- == dynamicColors.primaryFixed().getArgb(mDynamicSchemeLight))) {
+ == dynamicColors.primaryFixed().getArgb(
+ mLightColorScheme.getMaterialScheme()))) {
return false;
}
}
diff --git a/packages/SystemUI/tests/AndroidTest.xml b/packages/SystemUI/tests/AndroidTest.xml
index 31e7bd2..cd2a62d 100644
--- a/packages/SystemUI/tests/AndroidTest.xml
+++ b/packages/SystemUI/tests/AndroidTest.xml
@@ -32,4 +32,11 @@
<option name="test-filter-dir" value="/data/data/com.android.systemui.tests" />
<option name="hidden-api-checks" value="false"/>
</test>
+
+ <metrics_collector class="com.android.tradefed.device.metric.FilePullerLogCollector">
+ <option name="directory-keys"
+ value="/data/user/0/com.android.systemui.tests/files"/>
+ <option name="collect-on-run-ended-only" value="true"/>
+ <option name="clean-up" value="true"/>
+ </metrics_collector>
</configuration>
diff --git a/packages/SystemUI/tests/src/com/android/systemui/monet/ColorSchemeTest.kt b/packages/SystemUI/tests/src/com/android/systemui/monet/ColorSchemeTest.kt
new file mode 100644
index 0000000..261e8c0
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/monet/ColorSchemeTest.kt
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) 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 com.android.systemui.monet
+
+import android.test.suitebuilder.annotation.SmallTest
+import android.testing.AndroidTestingRunner
+import android.util.Log
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.theme.DynamicColors
+import com.google.ux.material.libmonet.hct.Hct
+import com.google.ux.material.libmonet.scheme.SchemeTonalSpot
+import java.io.File
+import java.io.FileWriter
+import java.io.StringWriter
+import javax.xml.parsers.DocumentBuilderFactory
+import javax.xml.transform.OutputKeys
+import javax.xml.transform.TransformerException
+import javax.xml.transform.TransformerFactory
+import javax.xml.transform.dom.DOMSource
+import javax.xml.transform.stream.StreamResult
+import kotlin.math.abs
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.w3c.dom.Document
+import org.w3c.dom.Element
+import org.w3c.dom.Node
+
+private const val fileHeader =
+ """
+ ~ Copyright (C) 2022 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.
+"""
+
+private fun testName(name: String): String {
+ return "Auto generated by: atest ColorSchemeTest#$name"
+}
+
+private const val commentRoles =
+ "Colors used in Android system, from design system. These " +
+ "values can be overlaid at runtime by OverlayManager RROs."
+
+private const val commentOverlay = "This value can be overlaid at runtime by OverlayManager RROs."
+
+private fun commentWhite(paletteName: String): String {
+ return "Lightest shade of the $paletteName color used by the system. White. $commentOverlay"
+}
+
+private fun commentBlack(paletteName: String): String {
+ return "Darkest shade of the $paletteName color used by the system. Black. $commentOverlay"
+}
+
+private fun commentShade(paletteName: String, tone: Int): String {
+ return "Shade of the $paletteName system color at $tone% perceptual luminance (L* in L*a*b* " +
+ "color space). $commentOverlay"
+}
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class ColorSchemeTest : SysuiTestCase() {
+ @Test
+ fun generateThemeStyles() {
+ val document = buildDoc<Any>()
+
+ val themes = document.createElement("themes")
+ document.appendWithBreak(themes)
+
+ var hue = 0.0
+ while (hue < 360) {
+ val sourceColor = Hct.from(hue, 50.0, 50.0)
+ val sourceColorHex = sourceColor.toInt().toRGBHex()
+
+ val theme = document.createElement("theme")
+ theme.setAttribute("color", sourceColorHex)
+ themes.appendChild(theme)
+
+ for (styleValue in Style.entries) {
+ if (
+ styleValue == Style.CLOCK ||
+ styleValue == Style.CLOCK_VIBRANT ||
+ styleValue == Style.CONTENT
+ ) {
+ continue
+ }
+
+ val style = document.createElement(styleValue.name.lowercase())
+ val colorScheme = ColorScheme(sourceColor.toInt(), false, styleValue)
+
+ style.appendChild(
+ document.createTextNode(
+ listOf(
+ colorScheme.accent1,
+ colorScheme.accent2,
+ colorScheme.accent3,
+ colorScheme.neutral1,
+ colorScheme.neutral2
+ )
+ .flatMap { a -> listOf(*a.allShades.toTypedArray()) }
+ .joinToString(",", transform = Int::toRGBHex)
+ )
+ )
+ theme.appendChild(style)
+ }
+
+ hue += 60
+ }
+
+ saveFile(document, "current_themes.xml")
+ }
+
+ @Test
+ fun generateDefaultValues() {
+ val document = buildDoc<Any>()
+
+ val resources = document.createElement("resources")
+ document.appendWithBreak(resources)
+
+ // shade colors
+ val colorScheme = ColorScheme(GOOGLE_BLUE, false)
+ arrayOf(
+ Triple("accent1", "Primary", colorScheme.accent1),
+ Triple("accent2", "Secondary", colorScheme.accent2),
+ Triple("accent3", "Tertiary", colorScheme.accent3),
+ Triple("neutral1", "Neutral", colorScheme.neutral1),
+ Triple("neutral2", "Secondary Neutral", colorScheme.neutral2)
+ )
+ .forEach {
+ val (paletteName, readable, palette) = it
+ palette.allShadesMapped.entries.forEachIndexed { index, (shade, colorValue) ->
+ val comment =
+ when (index) {
+ 0 -> commentWhite(readable)
+ palette.allShadesMapped.entries.size - 1 -> commentBlack(readable)
+ else -> commentShade(readable, abs(shade / 10 - 100))
+ }
+ resources.createColorEntry("system_${paletteName}_$shade", colorValue, comment)
+ }
+ }
+
+ resources.appendWithBreak(document.createComment(commentRoles), 2)
+
+ // dynamic colors
+ arrayOf(false, true).forEach { isDark ->
+ val suffix = if (isDark) "_dark" else "_light"
+ val dynamicScheme = SchemeTonalSpot(Hct.fromInt(GOOGLE_BLUE), isDark, 0.5)
+ DynamicColors.allDynamicColorsMapped(false).forEach {
+ resources.createColorEntry(
+ "system_${it.first}$suffix",
+ it.second.getArgb(dynamicScheme)
+ )
+ }
+ }
+
+ // fixed colors
+ val dynamicScheme = SchemeTonalSpot(Hct.fromInt(GOOGLE_BLUE), false, 0.5)
+ DynamicColors.getFixedColorsMapped(false).forEach {
+ resources.createColorEntry("system_${it.first}", it.second.getArgb(dynamicScheme))
+ }
+
+ saveFile(document, "role_values.xml")
+ }
+
+ // Helper Functions
+
+ private inline fun <reified T> buildDoc(): Document {
+ val functionName = T::class.simpleName + ""
+ val factory = DocumentBuilderFactory.newInstance()
+ val builder = factory.newDocumentBuilder()
+ val document = builder.newDocument()
+
+ document.appendWithBreak(document.createComment(fileHeader))
+ document.appendWithBreak(document.createComment(testName(functionName)))
+
+ return document
+ }
+
+ private fun documentToString(document: Document): String {
+ try {
+ val transformerFactory = TransformerFactory.newInstance()
+ val transformer = transformerFactory.newTransformer()
+ transformer.setOutputProperty(OutputKeys.MEDIA_TYPE, "application/xml")
+ transformer.setOutputProperty(OutputKeys.METHOD, "xml")
+ transformer.setOutputProperty(OutputKeys.INDENT, "yes")
+ transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4")
+
+ val stringWriter = StringWriter()
+ transformer.transform(DOMSource(document), StreamResult(stringWriter))
+ return stringWriter.toString()
+ } catch (e: TransformerException) {
+ throw RuntimeException("Error transforming XML", e)
+ }
+ }
+
+ private fun saveFile(document: Document, fileName: String) {
+ val outPath = context.filesDir.path + "/" + fileName
+ Log.d("ColorSchemeXml", "Artifact $fileName created")
+ val writer = FileWriter(File(outPath))
+ writer.write(documentToString(document))
+ writer.close()
+ }
+}
+
+private fun Element.createColorEntry(name: String, value: Int, comment: String? = null) {
+ val doc = this.ownerDocument
+
+ if (comment != null) {
+ this.appendChild(doc.createComment(comment))
+ }
+
+ val color = doc.createElement("color")
+ this.appendChild(color)
+
+ color.setAttribute("name", name)
+ color.appendChild(doc.createTextNode("#" + value.toRGBHex()))
+}
+
+private fun Node.appendWithBreak(child: Node, lineBreaks: Int = 1): Node {
+ val doc = if (this is Document) this else this.ownerDocument
+ val node = doc.createTextNode("\n".repeat(lineBreaks))
+ this.appendChild(node)
+ return this.appendChild(child)
+}
+
+private fun Int.toRGBHex(): String {
+ return "%06X".format(0xFFFFFF and this)
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java
index ab28a2f..ed7c956 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java
@@ -985,7 +985,7 @@
FabricatedOverlay neutrals = overlays[1];
FabricatedOverlay dynamic = overlays[2];
- final int colorsPerPalette = 12;
+ final int colorsPerPalette = 13;
// Color resources were added for all 3 accent palettes
verify(accents, times(colorsPerPalette * 3))
diff --git a/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java b/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java
index ff07619..9e3f5ce 100644
--- a/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java
+++ b/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java
@@ -18,6 +18,7 @@
import static android.content.pm.ActivityInfo.FLAG_CAN_DISPLAY_ON_REMOTE_DEVICES;
import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.Display.INVALID_DISPLAY;
import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
@@ -48,6 +49,8 @@
import com.android.modules.expresslog.Counter;
import java.util.Set;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
/**
* A controller to control the policies of the windows that can be displayed on the virtual display.
@@ -121,8 +124,12 @@
private final ComponentName mPermissionDialogComponent;
private final Object mGenericWindowPolicyControllerLock = new Object();
@Nullable private final ActivityBlockedCallback mActivityBlockedCallback;
+
+ // Do not access mDisplayId and mIsMirrorDisplay directly, instead use waitAndGetDisplayId()
+ // and waitAndGetIsMirrorDisplay()
private int mDisplayId = Display.INVALID_DISPLAY;
private boolean mIsMirrorDisplay = false;
+ private final CountDownLatch mDisplayIdSetLatch = new CountDownLatch(1);
@NonNull
@GuardedBy("mGenericWindowPolicyControllerLock")
@@ -214,6 +221,33 @@
void setDisplayId(int displayId, boolean isMirrorDisplay) {
mDisplayId = displayId;
mIsMirrorDisplay = isMirrorDisplay;
+ mDisplayIdSetLatch.countDown();
+ }
+
+ private int waitAndGetDisplayId() {
+ try {
+ if (!mDisplayIdSetLatch.await(10, TimeUnit.SECONDS)) {
+ Slog.e(TAG, "Timed out while waiting for GWPC displayId to be set.");
+ return INVALID_DISPLAY;
+ }
+ } catch (InterruptedException e) {
+ Slog.e(TAG, "Interrupted while waiting for GWPC displayId to be set.");
+ return INVALID_DISPLAY;
+ }
+ return mDisplayId;
+ }
+
+ private boolean waitAndGetIsMirrorDisplay() {
+ try {
+ if (!mDisplayIdSetLatch.await(10, TimeUnit.SECONDS)) {
+ Slog.e(TAG, "Timed out while waiting for GWPC isMirrorDisplay to be set.");
+ return false;
+ }
+ } catch (InterruptedException e) {
+ Slog.e(TAG, "Interrupted while waiting for GWPC isMirrorDisplay to be set.");
+ return false;
+ }
+ return mIsMirrorDisplay;
}
/**
@@ -281,7 +315,7 @@
@WindowConfiguration.WindowingMode int windowingMode, int launchingFromDisplayId,
boolean isNewTask) {
// Mirror displays cannot contain activities.
- if (mIsMirrorDisplay) {
+ if (waitAndGetIsMirrorDisplay()) {
Slog.d(TAG, "Mirror virtual displays cannot contain activities.");
return false;
}
@@ -341,11 +375,13 @@
@SuppressWarnings("AndroidFrameworkRequiresPermission")
public boolean keepActivityOnWindowFlagsChanged(ActivityInfo activityInfo, int windowFlags,
int systemWindowFlags) {
+ int displayId = waitAndGetDisplayId();
// The callback is fired only when windowFlags are changed. To let VirtualDevice owner
// aware that the virtual display has a secure window on top.
- if ((windowFlags & FLAG_SECURE) != 0 && mSecureWindowCallback != null) {
+ if ((windowFlags & FLAG_SECURE) != 0 && mSecureWindowCallback != null
+ && displayId != INVALID_DISPLAY) {
// Post callback on the main thread, so it doesn't block activity launching.
- mHandler.post(() -> mSecureWindowCallback.onSecureWindowShown(mDisplayId,
+ mHandler.post(() -> mSecureWindowCallback.onSecureWindowShown(displayId,
activityInfo.applicationInfo.uid));
}
@@ -365,13 +401,14 @@
@Override
public void onTopActivityChanged(ComponentName topActivity, int uid, @UserIdInt int userId) {
+ int displayId = waitAndGetDisplayId();
// Don't send onTopActivityChanged() callback when topActivity is null because it's defined
// as @NonNull in ActivityListener interface. Sends onDisplayEmpty() callback instead when
// there is no activity running on virtual display.
- if (mActivityListener != null && topActivity != null) {
+ if (mActivityListener != null && topActivity != null && displayId != INVALID_DISPLAY) {
// Post callback on the main thread so it doesn't block activity launching
mHandler.post(() ->
- mActivityListener.onTopActivityChanged(mDisplayId, topActivity, userId));
+ mActivityListener.onTopActivityChanged(displayId, topActivity, userId));
}
}
@@ -380,9 +417,11 @@
synchronized (mGenericWindowPolicyControllerLock) {
mRunningUids.clear();
mRunningUids.addAll(runningUids);
- if (mActivityListener != null && mRunningUids.isEmpty()) {
+ int displayId = waitAndGetDisplayId();
+ if (mActivityListener != null && mRunningUids.isEmpty()
+ && displayId != INVALID_DISPLAY) {
// Post callback on the main thread so it doesn't block activity launching
- mHandler.post(() -> mActivityListener.onDisplayEmpty(mDisplayId));
+ mHandler.post(() -> mActivityListener.onDisplayEmpty(displayId));
}
if (!mRunningAppsChangedListeners.isEmpty()) {
final ArraySet<RunningAppsChangedListener> listeners =
@@ -438,10 +477,12 @@
}
private void notifyActivityBlocked(ActivityInfo activityInfo) {
+ int displayId = waitAndGetDisplayId();
// Don't trigger activity blocked callback for mirror displays, because we can't show
// any activity or presentation on it anyway.
- if (!mIsMirrorDisplay && mActivityBlockedCallback != null) {
- mActivityBlockedCallback.onActivityBlocked(mDisplayId, activityInfo);
+ if (!waitAndGetIsMirrorDisplay() && mActivityBlockedCallback != null
+ && displayId != INVALID_DISPLAY) {
+ mActivityBlockedCallback.onActivityBlocked(displayId, activityInfo);
}
if (android.companion.virtualdevice.flags.Flags.metricsCollection()) {
Counter.logIncrementWithUid(
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 6ff8cf3..ea9ab30 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -3949,7 +3949,7 @@
UserspaceRebootLogger.noteUserspaceRebootWasRequested();
}
if (mHandler == null || !mSystemReady) {
- if (RescueParty.isAttemptingFactoryReset()) {
+ if (RescueParty.isRecoveryTriggeredReboot()) {
// If we're stuck in a really low-level reboot loop, and a
// rescue party is trying to prompt the user for a factory data
// reset, we must GET TO DA CHOPPA!
diff --git a/services/core/java/com/android/server/power/ShutdownThread.java b/services/core/java/com/android/server/power/ShutdownThread.java
index 4bf8a78..afcf49d 100644
--- a/services/core/java/com/android/server/power/ShutdownThread.java
+++ b/services/core/java/com/android/server/power/ShutdownThread.java
@@ -337,7 +337,7 @@
com.android.internal.R.string.reboot_to_update_reboot));
}
} else if (mReason != null && mReason.equals(PowerManager.REBOOT_RECOVERY)) {
- if (RescueParty.isAttemptingFactoryReset()) {
+ if (RescueParty.isRecoveryTriggeredReboot()) {
// We're not actually doing a factory reset yet; we're rebooting
// to ask the user if they'd like to reset, so give them a less
// scary dialog message.
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperDataParser.java b/services/core/java/com/android/server/wallpaper/WallpaperDataParser.java
index 65ab129..7f53ea3 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperDataParser.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperDataParser.java
@@ -336,6 +336,9 @@
parser.getAttributeInt(null, "cropRight" + pair.second, 0),
parser.getAttributeInt(null, "cropBottom" + pair.second, 0));
if (!cropHint.isEmpty()) wallpaper.mCropHints.put(pair.first, cropHint);
+ if (!cropHint.isEmpty() && cropHint.equals(legacyCropHint)) {
+ wallpaper.mOrientationWhenSet = pair.first;
+ }
}
if (wallpaper.mCropHints.size() == 0 && totalCropHint.isEmpty()) {
// migration case: the crops per screen orientation are not specified.
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index 6d8b030..080479d 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -2468,7 +2468,15 @@
for (WindowContainer<?> p = getAnimatableParent(wc); p != null;
p = getAnimatableParent(p)) {
final ChangeInfo parentChange = changes.get(p);
- if (parentChange == null || !parentChange.hasChanged()) break;
+ if (parentChange == null) {
+ break;
+ }
+ if (!parentChange.hasChanged()) {
+ // In case the target is collected after the parent has been changed, it could
+ // be too late to snapshot the parent change. Skip to see if there is any
+ // parent window further up to be considered as change parent.
+ continue;
+ }
if (p.mRemoteToken == null) {
// Intermediate parents must be those that has window to be managed by Shell.
continue;
diff --git a/services/tests/dreamservicetests/res/xml/test_dream_metadata.xml b/services/tests/dreamservicetests/res/xml/test_dream_metadata.xml
index 9211ec1..6e7d9ad 100644
--- a/services/tests/dreamservicetests/res/xml/test_dream_metadata.xml
+++ b/services/tests/dreamservicetests/res/xml/test_dream_metadata.xml
@@ -17,4 +17,6 @@
<dream xmlns:android="http://schemas.android.com/apk/res/android"
android:settingsActivity=
"com.android.frameworks.dreamservicetests/.TestDreamSettingsActivity"
- android:showClockAndComplications="false" />
+ android:showClockAndComplications="false"
+ android:dreamCategory="home_panel"
+ />
diff --git a/services/tests/dreamservicetests/src/com/android/server/dreams/DreamServiceTest.java b/services/tests/dreamservicetests/src/com/android/server/dreams/DreamServiceTest.java
index d231e40f..293ab7b 100644
--- a/services/tests/dreamservicetests/src/com/android/server/dreams/DreamServiceTest.java
+++ b/services/tests/dreamservicetests/src/com/android/server/dreams/DreamServiceTest.java
@@ -48,6 +48,7 @@
assertThat(metadata.settingsActivity).isEqualTo(
ComponentName.unflattenFromString(testSettingsActivity));
assertFalse(metadata.showComplications);
+ assertThat(metadata.dreamCategory).isEqualTo(DreamService.DREAM_CATEGORY_HOME_PANEL);
}
@Test
@@ -58,6 +59,7 @@
final DreamService.DreamMetadata metadata = getDreamMetadata(testDreamClassName);
assertThat(metadata.settingsActivity).isNull();
+ assertThat(metadata.dreamCategory).isEqualTo(DreamService.DREAM_CATEGORY_DEFAULT);
}
private DreamService.DreamMetadata getDreamMetadata(String dreamClassName)
diff --git a/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java b/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java
index 211a83d..c30ac2d 100644
--- a/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java
@@ -439,19 +439,19 @@
}
@Test
- public void testIsAttemptingFactoryReset() {
+ public void testIsRecoveryTriggeredReboot() {
for (int i = 0; i < LEVEL_FACTORY_RESET; i++) {
noteBoot(i + 1);
}
assertFalse(RescueParty.isFactoryResetPropertySet());
setCrashRecoveryPropAttemptingReboot(false);
noteBoot(LEVEL_FACTORY_RESET + 1);
- assertTrue(RescueParty.isAttemptingFactoryReset());
+ assertTrue(RescueParty.isRecoveryTriggeredReboot());
assertTrue(RescueParty.isFactoryResetPropertySet());
}
@Test
- public void testIsAttemptingFactoryResetOnlyAfterRebootCompleted() {
+ public void testIsRecoveryTriggeredRebootOnlyAfterRebootCompleted() {
for (int i = 0; i < LEVEL_FACTORY_RESET; i++) {
noteBoot(i + 1);
}
@@ -464,7 +464,7 @@
noteBoot(mitigationCount++);
setCrashRecoveryPropAttemptingReboot(false);
noteBoot(mitigationCount + 1);
- assertTrue(RescueParty.isAttemptingFactoryReset());
+ assertTrue(RescueParty.isRecoveryTriggeredReboot());
assertTrue(RescueParty.isFactoryResetPropertySet());
}
@@ -477,7 +477,7 @@
for (int i = 1; i <= LEVEL_FACTORY_RESET; i++) {
noteBoot(i);
}
- assertFalse(RescueParty.isAttemptingFactoryReset());
+ assertFalse(RescueParty.isRecoveryTriggeredReboot());
}
@Test
@@ -489,7 +489,7 @@
for (int i = 0; i <= LEVEL_FACTORY_RESET; i++) {
noteAppCrash(i + 1, true);
}
- assertFalse(RescueParty.isAttemptingFactoryReset());
+ assertFalse(RescueParty.isRecoveryTriggeredReboot());
}
@Test
@@ -501,7 +501,7 @@
for (int i = 1; i <= LEVEL_FACTORY_RESET; i++) {
noteBoot(i);
}
- assertTrue(RescueParty.isAttemptingFactoryReset());
+ assertTrue(RescueParty.isRecoveryTriggeredReboot());
}
@Test
public void testNotThrottlingAfterTimeoutOnAppCrash() {
@@ -512,7 +512,7 @@
for (int i = 0; i <= LEVEL_FACTORY_RESET; i++) {
noteAppCrash(i + 1, true);
}
- assertTrue(RescueParty.isAttemptingFactoryReset());
+ assertTrue(RescueParty.isRecoveryTriggeredReboot());
}
@Test
diff --git a/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java b/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java
index 2ff21ad..40537c8 100644
--- a/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java
+++ b/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java
@@ -978,8 +978,14 @@
shouldRestrictOverlayActivities = filteredAppProcessInfos.stream().anyMatch(pkg -> {
try {
- return mPackageManager.getProperty(PROPERTY_RESTRICT_USB_OVERLAY_ACTIVITIES, pkg)
- .getBoolean();
+ boolean restrictUsbOverlayActivitiesForPackage = mPackageManager
+ .getProperty(PROPERTY_RESTRICT_USB_OVERLAY_ACTIVITIES, pkg).getBoolean();
+
+ if (restrictUsbOverlayActivitiesForPackage) {
+ Slog.d(TAG, "restricting usb overlay activities as package " + pkg
+ + " is in foreground");
+ }
+ return restrictUsbOverlayActivitiesForPackage;
} catch (NameNotFoundException e) {
if (DEBUG) {
Slog.d(TAG, "property PROPERTY_RESTRICT_USB_OVERLAY_ACTIVITIES "
@@ -989,8 +995,8 @@
}
});
- if (shouldRestrictOverlayActivities) {
- Slog.d(TAG, "restricting starting of usb overlay activities");
+ if (!shouldRestrictOverlayActivities) {
+ Slog.d(TAG, "starting of usb overlay activities");
}
return shouldRestrictOverlayActivities;
}