Unify QS Headers in a ConstraintLayout
This is a POC and is missing several features: * Tight integration with the other surfaces to set margins * Expansion animation from QQS into QS * Privacy indicators To enable: adb shell am broadcast -a com.android.systemui.action.SET_FLAG --ei id 501 --ez 1 Test: manual Bug: 204204226 Change-Id: I5b2d5f5880ceff1adb1e4365cde15171c5c15d38
This commit is contained in:
114
packages/SystemUI/res/layout/combined_qs_header.xml
Normal file
114
packages/SystemUI/res/layout/combined_qs_header.xml
Normal file
@@ -0,0 +1,114 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ 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.
|
||||
-->
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/split_shade_status_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="@dimen/split_shade_header_min_height"
|
||||
android:clickable="false"
|
||||
android:focusable="true"
|
||||
android:paddingLeft="@dimen/qs_panel_padding"
|
||||
android:paddingRight="@dimen/qs_panel_padding"
|
||||
android:visibility="gone"
|
||||
android:theme="@style/Theme.SystemUI.QuickSettings.Header">
|
||||
|
||||
<androidx.constraintlayout.widget.Guideline
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/center"
|
||||
app:layout_constraintGuide_percent="0.5"
|
||||
android:orientation="vertical" />
|
||||
|
||||
<com.android.systemui.statusbar.policy.Clock
|
||||
android:id="@+id/clock"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintHeight_min="@dimen/split_shade_header_min_height"
|
||||
android:gravity="start|center_vertical"
|
||||
android:paddingStart="@dimen/status_bar_left_clock_starting_padding"
|
||||
android:paddingEnd="@dimen/status_bar_left_clock_end_padding"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="@style/TextAppearance.QS.Status"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/date"
|
||||
/>
|
||||
|
||||
<com.android.systemui.statusbar.policy.DateView
|
||||
android:id="@+id/date"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintHeight_min="@dimen/split_shade_header_min_height"
|
||||
android:layout_gravity="start|center_vertical"
|
||||
android:gravity="center_vertical"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="@style/TextAppearance.QS.Status"
|
||||
app:datePattern="@string/abbrev_wday_month_day_no_year_alarm"
|
||||
app:layout_constraintStart_toEndOf="@id/clock"
|
||||
app:layout_constraintEnd_toStartOf="@id/carrier_group"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0"
|
||||
/>
|
||||
|
||||
<include
|
||||
android:id="@+id/carrier_group"
|
||||
layout="@layout/qs_carrier_group"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintHeight_min="@dimen/split_shade_header_min_height"
|
||||
app:layout_constrainedWidth="true"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
android:layout_marginStart="8dp"
|
||||
android:focusable="false"
|
||||
android:minHeight="@dimen/split_shade_header_min_height"
|
||||
android:minWidth="48dp"
|
||||
app:layout_constraintStart_toEndOf="@id/date"
|
||||
app:layout_constraintEnd_toStartOf="@id/statusIcons"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintHorizontal_bias="1"
|
||||
/>
|
||||
|
||||
<com.android.systemui.statusbar.phone.StatusIconContainer
|
||||
android:id="@+id/statusIcons"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintHeight_min="@dimen/split_shade_header_min_height"
|
||||
android:paddingEnd="@dimen/signal_cluster_battery_padding"
|
||||
app:layout_constraintStart_toEndOf="@id/carrier_group"
|
||||
app:layout_constraintEnd_toStartOf="@id/batteryRemainingIcon"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
/>
|
||||
|
||||
<com.android.systemui.battery.BatteryMeterView
|
||||
android:id="@+id/batteryRemainingIcon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintHeight_min="@dimen/split_shade_header_min_height"
|
||||
app:textAppearance="@style/TextAppearance.QS.Status"
|
||||
app:layout_constraintStart_toEndOf="@id/statusIcons"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -79,7 +79,11 @@
|
||||
android:clipToPadding="false"
|
||||
android:clipChildren="false">
|
||||
|
||||
<include layout="@layout/split_shade_header"/>
|
||||
<ViewStub
|
||||
android:id="@+id/qs_header_stub"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
/>
|
||||
|
||||
<include
|
||||
layout="@layout/keyguard_status_view"
|
||||
|
||||
82
packages/SystemUI/res/xml/qqs_header.xml
Normal file
82
packages/SystemUI/res/xml/qqs_header.xml
Normal file
@@ -0,0 +1,82 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<ConstraintSet
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<Constraint
|
||||
android:id="@+id/clock"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/date"
|
||||
app:layout_constraintHorizontal_bias="0"
|
||||
app:layout_constraintHorizontal_chainStyle="packed"
|
||||
/>
|
||||
|
||||
<Constraint
|
||||
android:id="@+id/date"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintStart_toEndOf="@id/clock"
|
||||
app:layout_constraintEnd_toStartOf="@id/carrier_group"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0"
|
||||
/>
|
||||
|
||||
<Constraint
|
||||
android:id="@+id/carrier_group"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constrainedWidth="true"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
android:layout_marginStart="8dp"
|
||||
app:layout_constraintStart_toEndOf="@id/date"
|
||||
app:layout_constraintEnd_toStartOf="@id/statusIcons"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:visibility="invisible"
|
||||
app:layout_constraintHorizontal_bias="1"
|
||||
/>
|
||||
|
||||
<Constraint
|
||||
android:id="@+id/statusIcons"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintStart_toEndOf="@id/carrier_group"
|
||||
app:layout_constraintEnd_toStartOf="@id/batteryRemainingIcon"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintHorizontal_bias="1"
|
||||
/>
|
||||
|
||||
<Constraint
|
||||
android:id="@+id/batteryRemainingIcon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintStart_toEndOf="@id/statusIcons"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintHorizontal_bias="1"
|
||||
/>
|
||||
|
||||
</ConstraintSet>
|
||||
79
packages/SystemUI/res/xml/qs_header.xml
Normal file
79
packages/SystemUI/res/xml/qs_header.xml
Normal file
@@ -0,0 +1,79 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<ConstraintSet
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<Constraint
|
||||
android:id="@+id/clock"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="48dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/date"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/carrier_group"
|
||||
app:layout_constraintHorizontal_bias="0"
|
||||
/>
|
||||
|
||||
<Constraint
|
||||
android:id="@+id/date"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="48dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toTopOf="@id/clock"
|
||||
app:layout_constraintHorizontal_bias="0"
|
||||
/>
|
||||
|
||||
<Constraint
|
||||
android:id="@+id/carrier_group"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="48dp"
|
||||
app:layout_constrainedWidth="true"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
android:layout_marginStart="8dp"
|
||||
app:layout_constraintStart_toEndOf="@id/clock"
|
||||
app:layout_constraintEnd_toStartOf="@id/statusIcons"
|
||||
app:layout_constraintTop_toTopOf="@id/clock"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintHorizontal_bias="1"
|
||||
/>
|
||||
|
||||
<Constraint
|
||||
android:id="@+id/statusIcons"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="48dp"
|
||||
app:layout_constraintStart_toEndOf="@id/carrier_group"
|
||||
app:layout_constraintEnd_toStartOf="@id/batteryRemainingIcon"
|
||||
app:layout_constraintTop_toTopOf="@id/clock"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintHorizontal_bias="1"
|
||||
/>
|
||||
|
||||
<Constraint
|
||||
android:id="@+id/batteryRemainingIcon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="48dp"
|
||||
app:layout_constraintStart_toEndOf="@id/statusIcons"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@id/clock"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
/>
|
||||
|
||||
</ConstraintSet>
|
||||
77
packages/SystemUI/res/xml/split_header.xml
Normal file
77
packages/SystemUI/res/xml/split_header.xml
Normal file
@@ -0,0 +1,77 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<ConstraintSet
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<Constraint
|
||||
android:id="@+id/clock"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/date"
|
||||
/>
|
||||
|
||||
<Constraint
|
||||
android:id="@+id/date"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintStart_toEndOf="@id/clock"
|
||||
app:layout_constraintEnd_toStartOf="@id/carrier_group"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0"
|
||||
/>
|
||||
|
||||
<Constraint
|
||||
android:id="@+id/carrier_group"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constrainedWidth="true"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
android:layout_marginStart="8dp"
|
||||
app:layout_constraintStart_toEndOf="@id/date"
|
||||
app:layout_constraintEnd_toStartOf="@id/statusIcons"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintHorizontal_bias="1"
|
||||
/>
|
||||
|
||||
<Constraint
|
||||
android:id="@+id/statusIcons"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintStart_toEndOf="@id/carrier_group"
|
||||
app:layout_constraintEnd_toStartOf="@id/batteryRemainingIcon"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
/>
|
||||
|
||||
<Constraint
|
||||
android:id="@+id/batteryRemainingIcon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintStart_toEndOf="@id/statusIcons"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
/>
|
||||
|
||||
</ConstraintSet>
|
||||
@@ -187,6 +187,13 @@ public class FeatureFlags {
|
||||
return isEnabled(Flags.NEW_USER_SWITCHER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use the new single view QS headers
|
||||
*/
|
||||
public boolean useCombinedQSHeaders() {
|
||||
return isEnabled(Flags.COMBINED_QS_HEADERS);
|
||||
}
|
||||
|
||||
/** static method for the system setting */
|
||||
public static boolean isProviderModelSettingEnabled(Context context) {
|
||||
return FeatureFlagUtils.isEnabled(context, FeatureFlagUtils.SETTINGS_PROVIDER_MODEL);
|
||||
|
||||
@@ -77,21 +77,24 @@ public class Flags {
|
||||
public static final BooleanFlag NEW_USER_SWITCHER =
|
||||
new BooleanFlag(500, true);
|
||||
|
||||
public static final BooleanFlag COMBINED_QS_HEADERS =
|
||||
new BooleanFlag(501, false);
|
||||
|
||||
/***************************************/
|
||||
// 600- status bar
|
||||
public static final BooleanFlag COMBINED_STATUS_BAR_SIGNAL_ICONS =
|
||||
new BooleanFlag(501, false);
|
||||
new BooleanFlag(601, false);
|
||||
|
||||
/***************************************/
|
||||
// 700 - dialer/calls
|
||||
public static final BooleanFlag ONGOING_CALL_STATUS_BAR_CHIP =
|
||||
new BooleanFlag(600, true);
|
||||
new BooleanFlag(700, true);
|
||||
|
||||
public static final BooleanFlag ONGOING_CALL_IN_IMMERSIVE =
|
||||
new BooleanFlag(601, true);
|
||||
new BooleanFlag(701, true);
|
||||
|
||||
public static final BooleanFlag ONGOING_CALL_IN_IMMERSIVE_CHIP_TAP =
|
||||
new BooleanFlag(602, true);
|
||||
new BooleanFlag(702, true);
|
||||
|
||||
// Pay no attention to the reflection behind the curtain.
|
||||
// ========================== Curtain ==========================
|
||||
|
||||
@@ -103,6 +103,8 @@ public class QuickStatusBarHeader extends FrameLayout {
|
||||
private boolean mHasCenterCutout;
|
||||
private boolean mConfigShowBatteryEstimate;
|
||||
|
||||
private boolean mUseCombinedQSHeader;
|
||||
|
||||
public QuickStatusBarHeader(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
@@ -160,7 +162,9 @@ public class QuickStatusBarHeader extends FrameLayout {
|
||||
void onAttach(TintedIconManager iconManager,
|
||||
QSExpansionPathInterpolator qsExpansionPathInterpolator,
|
||||
List<String> rssiIgnoredSlots,
|
||||
StatusBarContentInsetsProvider insetsProvider) {
|
||||
StatusBarContentInsetsProvider insetsProvider,
|
||||
boolean useCombinedQSHeader) {
|
||||
mUseCombinedQSHeader = useCombinedQSHeader;
|
||||
mTintedIconManager = iconManager;
|
||||
mRssiIgnoredSlots = rssiIgnoredSlots;
|
||||
mInsetsProvider = insetsProvider;
|
||||
@@ -236,8 +240,11 @@ public class QuickStatusBarHeader extends FrameLayout {
|
||||
// status bar is already displayed out of QS in split shade
|
||||
boolean shouldUseSplitShade =
|
||||
resources.getBoolean(R.bool.config_use_split_notification_shade);
|
||||
mStatusIconsView.setVisibility(shouldUseSplitShade ? View.GONE : View.VISIBLE);
|
||||
mDatePrivacyView.setVisibility(shouldUseSplitShade ? View.GONE : View.VISIBLE);
|
||||
|
||||
mStatusIconsView.setVisibility(
|
||||
shouldUseSplitShade || mUseCombinedQSHeader ? View.GONE : View.VISIBLE);
|
||||
mDatePrivacyView.setVisibility(
|
||||
shouldUseSplitShade || mUseCombinedQSHeader ? View.GONE : View.VISIBLE);
|
||||
|
||||
mConfigShowBatteryEstimate = resources.getBoolean(R.bool.config_showBatteryEstimateQSBH);
|
||||
|
||||
@@ -276,8 +283,8 @@ public class QuickStatusBarHeader extends FrameLayout {
|
||||
}
|
||||
|
||||
MarginLayoutParams qqsLP = (MarginLayoutParams) mHeaderQsPanel.getLayoutParams();
|
||||
qqsLP.topMargin = mContext.getResources()
|
||||
.getDimensionPixelSize(R.dimen.qqs_layout_margin_top);
|
||||
qqsLP.topMargin = shouldUseSplitShade || !mUseCombinedQSHeader ? mContext.getResources()
|
||||
.getDimensionPixelSize(R.dimen.qqs_layout_margin_top) : qsOffsetHeight;
|
||||
mHeaderQsPanel.setLayoutParams(qqsLP);
|
||||
|
||||
updateBatteryMode();
|
||||
|
||||
@@ -229,8 +229,8 @@ class QuickStatusBarHeaderController extends ViewController<QuickStatusBarHeader
|
||||
);
|
||||
}
|
||||
|
||||
mView.onAttach(
|
||||
mIconManager, mQSExpansionPathInterpolator, rssiIgnoredSlots, mInsetsProvider);
|
||||
mView.onAttach(mIconManager, mQSExpansionPathInterpolator, rssiIgnoredSlots,
|
||||
mInsetsProvider, mFeatureFlags.useCombinedQSHeaders());
|
||||
|
||||
mDemoModeController.addCallback(mDemoModeReceiver);
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ import static androidx.constraintlayout.widget.ConstraintSet.END;
|
||||
import static androidx.constraintlayout.widget.ConstraintSet.PARENT_ID;
|
||||
import static androidx.constraintlayout.widget.ConstraintSet.START;
|
||||
import static androidx.constraintlayout.widget.ConstraintSet.TOP;
|
||||
import static androidx.constraintlayout.widget.ConstraintSet.WRAP_CONTENT;
|
||||
|
||||
import static com.android.internal.jank.InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE;
|
||||
import static com.android.keyguard.KeyguardClockSwitch.LARGE;
|
||||
@@ -451,6 +452,9 @@ public class NotificationPanelViewController extends PanelViewController {
|
||||
private boolean mIsFullWidth;
|
||||
private boolean mBlockingExpansionForCurrentTouch;
|
||||
|
||||
// TODO (b/204204226): no longer needed once refactor is complete
|
||||
private final boolean mUseCombinedQSHeaders;
|
||||
|
||||
/**
|
||||
* Following variables maintain state of events when input focus transfer may occur.
|
||||
*/
|
||||
@@ -890,6 +894,8 @@ public class NotificationPanelViewController extends PanelViewController {
|
||||
mMaxKeyguardNotifications = resources.getInteger(R.integer.keyguard_max_notification_count);
|
||||
updateUserSwitcherFlags();
|
||||
onFinishInflate();
|
||||
|
||||
mUseCombinedQSHeaders = featureFlags.useCombinedQSHeaders();
|
||||
}
|
||||
|
||||
private void onFinishInflate() {
|
||||
@@ -1118,6 +1124,9 @@ public class NotificationPanelViewController extends PanelViewController {
|
||||
} else {
|
||||
constraintSet.connect(R.id.qs_frame, END, PARENT_ID, END);
|
||||
constraintSet.connect(R.id.notification_stack_scroller, START, PARENT_ID, START);
|
||||
if (mUseCombinedQSHeaders) {
|
||||
constraintSet.constrainHeight(R.id.split_shade_status_bar, WRAP_CONTENT);
|
||||
}
|
||||
}
|
||||
constraintSet.getConstraint(R.id.notification_stack_scroller).layout.mWidth = panelWidth;
|
||||
constraintSet.getConstraint(R.id.qs_frame).layout.mWidth = qsWidth;
|
||||
@@ -2366,6 +2375,7 @@ public class NotificationPanelViewController extends PanelViewController {
|
||||
float qsExpansionFraction = computeQsExpansionFraction();
|
||||
mQs.setQsExpansion(qsExpansionFraction, getExpandedFraction(), getHeaderTranslation(),
|
||||
mNotificationStackScrollLayoutController.getNotificationSquishinessFraction());
|
||||
mSplitShadeHeaderController.setQsExpandedFraction(qsExpansionFraction);
|
||||
mMediaHierarchyManager.setQsExpansion(qsExpansionFraction);
|
||||
int qsPanelBottomY = calculateQsBottomPosition(qsExpansionFraction);
|
||||
mScrimController.setQsPosition(qsExpansionFraction, qsPanelBottomY);
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
package com.android.systemui.statusbar.phone
|
||||
|
||||
import android.view.View
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.constraintlayout.widget.ConstraintSet
|
||||
import com.android.systemui.R
|
||||
import com.android.systemui.animation.ShadeInterpolation
|
||||
import com.android.systemui.battery.BatteryMeterView
|
||||
@@ -37,6 +39,7 @@ class SplitShadeHeaderController @Inject constructor(
|
||||
batteryMeterViewController: BatteryMeterViewController
|
||||
) {
|
||||
|
||||
private val combinedHeaders = featureFlags.useCombinedQSHeaders()
|
||||
// TODO(b/194178072) Handle RSSI hiding when multi carrier
|
||||
private val iconManager: StatusBarIconController.IconManager
|
||||
private val qsCarrierGroupController: QSCarrierGroupController
|
||||
@@ -75,6 +78,19 @@ class SplitShadeHeaderController @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
var qsExpandedFraction = -1f
|
||||
set(value) {
|
||||
if (visible && field != value) {
|
||||
field = value
|
||||
updateVisibility()
|
||||
}
|
||||
}
|
||||
|
||||
private val constraintSplit = ConstraintSet()
|
||||
.apply { load(statusBar.context, R.xml.split_header) }
|
||||
private val constraintQQS = ConstraintSet().apply { load(statusBar.context, R.xml.qqs_header) }
|
||||
private val constraintQS = ConstraintSet().apply { load(statusBar.context, R.xml.qs_header) }
|
||||
|
||||
init {
|
||||
batteryMeterViewController.init()
|
||||
val batteryIcon: BatteryMeterView = statusBar.findViewById(R.id.batteryRemainingIcon)
|
||||
@@ -91,7 +107,7 @@ class SplitShadeHeaderController @Inject constructor(
|
||||
}
|
||||
|
||||
private fun updateVisibility() {
|
||||
val visibility = if (!splitShadeMode) {
|
||||
val visibility = if (!splitShadeMode && !combinedHeaders) {
|
||||
View.GONE
|
||||
} else if (shadeExpanded) {
|
||||
View.VISIBLE
|
||||
@@ -102,6 +118,21 @@ class SplitShadeHeaderController @Inject constructor(
|
||||
statusBar.visibility = visibility
|
||||
visible = visibility == View.VISIBLE
|
||||
}
|
||||
updateConstraints()
|
||||
}
|
||||
|
||||
private fun updateConstraints() {
|
||||
if (!combinedHeaders) {
|
||||
return
|
||||
}
|
||||
statusBar as ConstraintLayout
|
||||
if (splitShadeMode) {
|
||||
constraintSplit.applyTo(statusBar)
|
||||
} else if (qsExpandedFraction == 1f) {
|
||||
constraintQS.applyTo(statusBar)
|
||||
} else {
|
||||
constraintQQS.applyTo(statusBar)
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateListeners() {
|
||||
|
||||
@@ -19,11 +19,13 @@ package com.android.systemui.statusbar.phone.dagger;
|
||||
import android.annotation.Nullable;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewStub;
|
||||
|
||||
import com.android.keyguard.LockIconView;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.battery.BatteryMeterView;
|
||||
import com.android.systemui.biometrics.AuthRippleView;
|
||||
import com.android.systemui.flags.FeatureFlags;
|
||||
import com.android.systemui.statusbar.NotificationShelf;
|
||||
import com.android.systemui.statusbar.NotificationShelfController;
|
||||
import com.android.systemui.statusbar.notification.row.dagger.NotificationShelfComponent;
|
||||
@@ -126,9 +128,16 @@ public abstract class StatusBarViewModule {
|
||||
@Provides
|
||||
@Named(SPLIT_SHADE_HEADER)
|
||||
@StatusBarComponent.StatusBarScope
|
||||
public static View getSlitShadeStatusBarView(
|
||||
NotificationShadeWindowView notificationShadeWindowView) {
|
||||
return notificationShadeWindowView.findViewById(R.id.split_shade_status_bar);
|
||||
public static View getSplitShadeStatusBarView(
|
||||
NotificationShadeWindowView notificationShadeWindowView,
|
||||
FeatureFlags featureFlags) {
|
||||
ViewStub stub = notificationShadeWindowView.findViewById(R.id.qs_header_stub);
|
||||
int layoutId = featureFlags.useCombinedQSHeaders()
|
||||
? R.layout.combined_qs_header
|
||||
: R.layout.split_shade_header;
|
||||
stub.setLayoutResource(layoutId);
|
||||
View v = stub.inflate();
|
||||
return v;
|
||||
}
|
||||
|
||||
/** */
|
||||
|
||||
@@ -51,6 +51,7 @@ import org.junit.runner.RunWith
|
||||
import org.mockito.Answers
|
||||
import org.mockito.ArgumentMatchers.anyInt
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito.anyBoolean
|
||||
import org.mockito.Mockito.reset
|
||||
import org.mockito.Mockito.verify
|
||||
import org.mockito.Mockito.`when`
|
||||
@@ -251,7 +252,7 @@ class QuickStatusBarHeaderControllerTest : SysuiTestCase() {
|
||||
controller.init()
|
||||
|
||||
val captor = argumentCaptor<List<String>>()
|
||||
verify(view).onAttach(any(), any(), capture(captor), any())
|
||||
verify(view).onAttach(any(), any(), capture(captor), any(), anyBoolean())
|
||||
|
||||
assertThat(captor.value).containsExactly(
|
||||
mContext.getString(com.android.internal.R.string.status_bar_mobile)
|
||||
@@ -264,7 +265,7 @@ class QuickStatusBarHeaderControllerTest : SysuiTestCase() {
|
||||
controller.init()
|
||||
|
||||
val captor = argumentCaptor<List<String>>()
|
||||
verify(view).onAttach(any(), any(), capture(captor), any())
|
||||
verify(view).onAttach(any(), any(), capture(captor), any(), anyBoolean())
|
||||
|
||||
assertThat(captor.value).containsExactly(
|
||||
mContext.getString(com.android.internal.R.string.status_bar_no_calling),
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package com.android.systemui.statusbar.phone
|
||||
|
||||
import android.content.Context
|
||||
import android.content.res.Resources
|
||||
import android.test.suitebuilder.annotation.SmallTest
|
||||
import android.testing.AndroidTestingRunner
|
||||
import android.view.View
|
||||
import com.android.systemui.R
|
||||
import com.android.systemui.SysuiTestCase
|
||||
@@ -15,14 +14,16 @@ import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.ArgumentMatchers.any
|
||||
import org.mockito.ArgumentMatchers.anyInt
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito.`when` as whenever
|
||||
import org.mockito.Mockito.verify
|
||||
import org.mockito.junit.MockitoJUnit
|
||||
import org.mockito.Mockito.`when` as whenever
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidTestingRunner::class)
|
||||
class SplitShadeHeaderControllerTest : SysuiTestCase() {
|
||||
|
||||
@Mock private lateinit var view: View
|
||||
@@ -33,8 +34,6 @@ class SplitShadeHeaderControllerTest : SysuiTestCase() {
|
||||
@Mock private lateinit var featureFlags: FeatureFlags
|
||||
@Mock private lateinit var batteryMeterView: BatteryMeterView
|
||||
@Mock private lateinit var batteryMeterViewController: BatteryMeterViewController
|
||||
@Mock private lateinit var resources: Resources
|
||||
@Mock private lateinit var context: Context
|
||||
@JvmField @Rule val mockitoRule = MockitoJUnit.rule()
|
||||
var viewVisibility = View.GONE
|
||||
|
||||
@@ -45,8 +44,8 @@ class SplitShadeHeaderControllerTest : SysuiTestCase() {
|
||||
whenever<BatteryMeterView>(view.findViewById(R.id.batteryRemainingIcon))
|
||||
.thenReturn(batteryMeterView)
|
||||
whenever<StatusIconContainer>(view.findViewById(R.id.statusIcons)).thenReturn(statusIcons)
|
||||
whenever(view.context).thenReturn(context)
|
||||
whenever(statusIcons.context).thenReturn(context)
|
||||
whenever(context.resources).thenReturn(resources)
|
||||
whenever(qsCarrierGroupControllerBuilder.setQSCarrierGroup(any()))
|
||||
.thenReturn(qsCarrierGroupControllerBuilder)
|
||||
whenever(qsCarrierGroupControllerBuilder.build()).thenReturn(qsCarrierGroupController)
|
||||
@@ -55,6 +54,7 @@ class SplitShadeHeaderControllerTest : SysuiTestCase() {
|
||||
null
|
||||
}
|
||||
whenever(view.visibility).thenAnswer { _ -> viewVisibility }
|
||||
whenever(featureFlags.useCombinedQSHeaders()).thenReturn(false)
|
||||
splitShadeHeaderController = SplitShadeHeaderController(view, statusBarIconController,
|
||||
qsCarrierGroupControllerBuilder, featureFlags, batteryMeterViewController)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user