Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 99692410 authored by Fabian Kozynski's avatar Fabian Kozynski Committed by Android (Google) Code Review
Browse files

Merge changes Ib9407914,I63dbe8fa into sc-dev

* changes:
  Add chevron to tiles that expand instead of toggling.
  Refactor QSTileView hierarchy
parents 38e2d409 cd7ecf7d
Loading
Loading
Loading
Loading
+1.73 KiB (77.8 KiB)
Loading image diff...
+7 −7
Original line number Diff line number Diff line
@@ -8,7 +8,7 @@ This document is a more or less comprehensive summary of the state and infrastru

## What are Quick Settings Tiles?

Quick Settings (from now on, QS) is the expanded panel that contains shortcuts for the user to toggle many settings. This is opened by expanding the notification drawer twice (or once when phone is locked). Quick Quick Settings (QQS) is the smaller panel that appears on top of the notifications before expanding twice and contains some of the toggles with no text.
Quick Settings (from now on, QS) is the expanded panel that contains shortcuts for the user to toggle many settings. This is opened by expanding the notification drawer twice (or once when phone is locked). Quick Quick Settings (QQS) is the smaller panel that appears on top of the notifications before expanding twice and contains some of the toggles with no secondary line.

Each of these toggles that appear either in QS or QQS are called Quick Settings Tiles (or tiles for short). They allow the user to enable or disable settings quickly and sometimes provides access to more comprehensive settings pages.

@@ -69,13 +69,13 @@ For more information on how to implement a tile in SystemUI, see [Implementing a

Each Tile has a couple of associated views for displaying it in QS and QQS. These views are updated after the backend updates the `State` using `QSTileImpl#handleUpdateState`.

* **[`com.android.systemui.plugins.qs.QSTileView`](/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTileView.java)**: Abstract class that provides basic Tile functionality. These allows external [Factories](#qsfactory) to create Tiles.
* **[`QSTileBaseView`](/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileBaseView.java)**: Implementation of `QSTileView` used in QQS that takes care of most of the features of the view:
* **[`QSTileView`](/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTileView.java)**: Abstract class that provides basic Tile functionality. These allows external [Factories](#qsfactory) to create Tiles.
* **[`QSTileViewImpl`](/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.java)**: Implementation of `QSTileView`. It takes care of the following:
  * Holding the icon
  * Background color and shape
  * Ripple
  * Click listening
* **[`QSTileView`](/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileView.java)**: Extends `QSTileBaseView`to add label support. Used in QS.
  * Labels
* **[`QSIconView`](/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSIconView.java)**
* **[`QSIconViewImpl`](/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java)**

@@ -103,7 +103,7 @@ When a container for tiles (`QuickQSPanel` or `QSPanel`) has to display tiles, t
This is a brief run-down of what happens when a user clicks on a tile. Internal changes on the device (for example, changes from Settings) will trigger this process starting in step 3. Throughout this section, we assume that we are dealing with a `QSTileImpl`.

1. User clicks on tile. The following calls happen in sequence:
   1. `QSTileBaseView#onClickListener`.
   1. `QSTileViewImpl#onClickListener`.
   2. `QSTile#click`.
   3. `QSTileImpl#handleClick`. This last call sets the new state for the device by using the associated controller.
2. State in the device changes. This is normally outside of SystemUI's control.
@@ -113,9 +113,9 @@ This is a brief run-down of what happens when a user clicks on a tile. Internal
4. `QSTileImpl#handleUpdateState` is called to update the state with the new information. This information can be obtained both from the `Object` passed to `refreshState` as well as from the controller.
5. If the state has changed (in at least one element), `QSTileImpl#handleStateChanged` is called. This will trigger a call to all the associated `QSTile.Callback#onStateChanged`, passing the new `State`.
6. `QSTileView#onStateChanged` is called and this calls `QSTileView#handleStateChanged`. This method maps the state into the view:
   * The tile is rippled and the color changes to match the new state.
   * The tile colors change to match the new state.
   * `QSIconView.setIcon` is called to apply the correct state to the icon and the correct icon to the view.
   * If the tile is a `QSTileView` (in expanded QS), the labels are changed.
   * The tile labels change to match the new state.

## Third party tiles (TileService)

+10 −5
Original line number Diff line number Diff line
@@ -163,7 +163,7 @@ public interface QSTile {
        public SlashState slash;
        public boolean handlesLongClick = true;
        public boolean showRippleEffect = true;
        public Drawable sideViewDrawable;
        public Drawable sideViewCustomDrawable;

        public boolean copyTo(State other) {
            if (other == null) throw new IllegalArgumentException();
@@ -185,7 +185,7 @@ public interface QSTile {
                    || !Objects.equals(other.slash, slash)
                    || !Objects.equals(other.handlesLongClick, handlesLongClick)
                    || !Objects.equals(other.showRippleEffect, showRippleEffect)
                    || !Objects.equals(other.sideViewDrawable, sideViewDrawable);
                    || !Objects.equals(other.sideViewCustomDrawable, sideViewCustomDrawable);
            other.icon = icon;
            other.iconSupplier = iconSupplier;
            other.label = label;
@@ -201,7 +201,7 @@ public interface QSTile {
            other.slash = slash != null ? slash.copy() : null;
            other.handlesLongClick = handlesLongClick;
            other.showRippleEffect = showRippleEffect;
            other.sideViewDrawable = sideViewDrawable;
            other.sideViewCustomDrawable = sideViewCustomDrawable;
            return changed;
        }

@@ -227,7 +227,7 @@ public interface QSTile {
            sb.append(",isTransient=").append(isTransient);
            sb.append(",state=").append(state);
            sb.append(",slash=\"").append(slash).append("\"");
            sb.append(",sideViewDrawable").append(sideViewDrawable);
            sb.append(",sideViewCustomDrawable=").append(sideViewCustomDrawable);
            return sb.append(']');
        }

@@ -242,12 +242,16 @@ public interface QSTile {
    public static class BooleanState extends State {
        public static final int VERSION = 1;
        public boolean value;
        public boolean forceExpandIcon;

        @Override
        public boolean copyTo(State other) {
            final BooleanState o = (BooleanState) other;
            final boolean changed = super.copyTo(other) || o.value != value;
            final boolean changed = super.copyTo(other)
                    || o.value != value
                    || o.forceExpandIcon != forceExpandIcon;
            o.value = value;
            o.forceExpandIcon = forceExpandIcon;
            return changed;
        }

@@ -255,6 +259,7 @@ public interface QSTile {
        protected StringBuilder toStringBuilder() {
            final StringBuilder rt = super.toStringBuilder();
            rt.insert(rt.length() - 1, ",value=" + value);
            rt.insert(rt.length() - 1, ",forceExpandIcon=" + forceExpandIcon);
            return rt;
        }

+18 −64
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
    Copyright (C) 2016 The Android Open Source Project
    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.
@@ -14,84 +14,38 @@
    See the License for the specific language governing permissions and
    limitations under the License.
-->
<com.android.systemui.qs.tileimpl.ButtonRelativeLayout
<com.android.systemui.qs.tileimpl.IgnorableChildLinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_weight="1"
    android:clipChildren="false"
    android:clipToPadding="false"
    android:paddingTop="12dp">
    <LinearLayout
        android:id="@+id/label_group"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:gravity="center"
        android:clipChildren="false"
        android:clipToPadding="false"
        android:orientation="horizontal">
        <Space
            android:id="@+id/expand_space"
            android:layout_width="22dp"
            android:layout_height="0dp"
            android:visibility="gone" />
    android:orientation="vertical"
    android:layout_marginStart="@dimen/qs_label_container_margin"
    android:layout_marginEnd="0dp"
    android:layout_gravity="center_vertical | start">

    <TextView
        android:id="@+id/tile_label"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
            android:clickable="false"
            android:padding="0dp"
            android:gravity="center"
        android:gravity="start"
        android:textDirection="locale"
        android:ellipsize="marquee"
        android:singleLine="true"
        android:textAppearance="@style/TextAppearance.QS.TileLabel"/>

        <ImageView android:id="@+id/restricted_padlock"
            android:layout_width="@dimen/qs_tile_text_size"
            android:layout_height="match_parent"
            android:paddingBottom="@dimen/qs_tile_text_size"
            android:src="@drawable/ic_info"
            android:layout_marginLeft="@dimen/restricted_padlock_pading"
            android:scaleType="centerInside"
            android:visibility="gone" />

        <ImageView
            android:id="@+id/expand_indicator"
            android:layout_marginStart="4dp"
            android:layout_width="18dp"
            android:layout_height="match_parent"
            android:src="@drawable/qs_dual_tile_caret"
            android:tint="?android:attr/textColorPrimary"
            android:visibility="gone" />
    </LinearLayout>

    <TextView
        android:id="@+id/app_label"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignStart="@id/label_group"
        android:layout_alignEnd="@id/label_group"
        android:layout_below="@id/label_group"
        android:clickable="false"
        android:gravity="start"
        android:textDirection="locale"
        android:ellipsize="marquee"
        android:singleLine="true"
        android:padding="0dp"
        android:visibility="gone"
        android:gravity="center"
        android:textAppearance="@style/TextAppearance.QS.TileLabel.Secondary"
        android:textColor="?android:attr/textColorSecondary"/>

    <View
        android:id="@+id/underline"
        android:layout_width="30dp"
        android:layout_height="1dp"
        android:layout_marginTop="2dp"
        android:layout_alignStart="@id/label_group"
        android:layout_alignEnd="@id/label_group"
        android:layout_below="@id/label_group"
        android:visibility="gone"
        android:alpha="?android:attr/disabledAlpha"
        android:background="?android:attr/colorForeground"/>

</com.android.systemui.qs.tileimpl.ButtonRelativeLayout>
</com.android.systemui.qs.tileimpl.IgnorableChildLinearLayout>
+41 −0
Original line number Diff line number Diff line
<?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.
-->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="@dimen/qs_label_container_margin"
    android:layout_gravity="center_vertical | end"
>
    <ImageView
        android:id="@+id/customDrawable"
        android:layout_width="wrap_content"
        android:layout_height="@dimen/qs_icon_size"
        android:layout_marginEnd="@dimen/qs_drawable_end_margin"
        android:adjustViewBounds="true"
        android:scaleType="fitCenter"
        android:visibility="gone"
    />

    <ImageView
        android:id="@+id/chevron"
        android:layout_width="@dimen/qs_icon_size"
        android:layout_height="@dimen/qs_icon_size"
        android:src="@*android:drawable/ic_chevron_end"
        android:visibility="gone"
        android:importantForAccessibility="no"
    />
</FrameLayout>
 No newline at end of file
Loading