1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5  * except in compliance with the License. You may obtain a copy of the License at
6  *
7  *      http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software distributed under the
10  * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
11  * KIND, either express or implied. See the License for the specific language governing
12  * permissions and limitations under the License.
13  */
14 
15 package com.android.systemui.qs.tileimpl;
16 
17 import android.content.Context;
18 import android.content.res.ColorStateList;
19 import android.content.res.Configuration;
20 import android.service.quicksettings.Tile;
21 import android.text.TextUtils;
22 import android.view.Gravity;
23 import android.view.LayoutInflater;
24 import android.view.View;
25 import android.view.ViewGroup;
26 import android.widget.ImageView;
27 import android.widget.TextView;
28 
29 import com.android.settingslib.Utils;
30 import com.android.systemui.FontSizeUtils;
31 import com.android.systemui.R;
32 import com.android.systemui.plugins.qs.QSIconView;
33 import com.android.systemui.plugins.qs.QSTile;
34 
35 import java.util.Objects;
36 
37 /** View that represents a standard quick settings tile. **/
38 public class QSTileView extends QSTileBaseView {
39     private static final int MAX_LABEL_LINES = 2;
40     private static final boolean DUAL_TARGET_ALLOWED = false;
41     private View mDivider;
42     protected TextView mLabel;
43     protected TextView mSecondLine;
44     private ImageView mPadLock;
45     private int mState;
46     private ViewGroup mLabelContainer;
47     private View mExpandIndicator;
48     private View mExpandSpace;
49     private ColorStateList mColorLabelDefault;
50     private ColorStateList mColorLabelUnavailable;
51 
QSTileView(Context context, QSIconView icon)52     public QSTileView(Context context, QSIconView icon) {
53         this(context, icon, false);
54     }
55 
QSTileView(Context context, QSIconView icon, boolean collapsedView)56     public QSTileView(Context context, QSIconView icon, boolean collapsedView) {
57         super(context, icon, collapsedView);
58 
59         setClipChildren(false);
60         setClipToPadding(false);
61 
62         setClickable(true);
63         setId(View.generateViewId());
64         createLabel();
65         setOrientation(VERTICAL);
66         setGravity(Gravity.CENTER_HORIZONTAL | Gravity.TOP);
67         mColorLabelDefault = Utils.getColorAttr(getContext(), android.R.attr.textColorPrimary);
68         // The text color for unavailable tiles is textColorSecondary, same as secondaryLabel for
69         // contrast purposes
70         mColorLabelUnavailable = Utils.getColorAttr(getContext(),
71                 android.R.attr.textColorSecondary);
72     }
73 
getLabel()74     TextView getLabel() {
75         return mLabel;
76     }
77 
78     @Override
onConfigurationChanged(Configuration newConfig)79     protected void onConfigurationChanged(Configuration newConfig) {
80         super.onConfigurationChanged(newConfig);
81         FontSizeUtils.updateFontSize(mLabel, R.dimen.qs_tile_text_size);
82         FontSizeUtils.updateFontSize(mSecondLine, R.dimen.qs_tile_text_size);
83     }
84 
85     @Override
getDetailY()86     public int getDetailY() {
87         return getTop() + mLabelContainer.getTop() + mLabelContainer.getHeight() / 2;
88     }
89 
createLabel()90     protected void createLabel() {
91         mLabelContainer = (ViewGroup) LayoutInflater.from(getContext())
92                 .inflate(R.layout.qs_tile_label, this, false);
93         mLabelContainer.setClipChildren(false);
94         mLabelContainer.setClipToPadding(false);
95         mLabel = mLabelContainer.findViewById(R.id.tile_label);
96         mPadLock = mLabelContainer.findViewById(R.id.restricted_padlock);
97         mDivider = mLabelContainer.findViewById(R.id.underline);
98         mExpandIndicator = mLabelContainer.findViewById(R.id.expand_indicator);
99         mExpandSpace = mLabelContainer.findViewById(R.id.expand_space);
100         mSecondLine = mLabelContainer.findViewById(R.id.app_label);
101         addView(mLabelContainer);
102     }
103 
104     @Override
onMeasure(int widthMeasureSpec, int heightMeasureSpec)105     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
106         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
107 
108         // Remeasure view if the primary label requires more then 2 lines or the secondary label
109         // text will be cut off.
110         if (mLabel.getLineCount() > MAX_LABEL_LINES || !TextUtils.isEmpty(mSecondLine.getText())
111                         && mSecondLine.getLineHeight() > mSecondLine.getHeight()) {
112             mLabel.setSingleLine();
113             super.onMeasure(widthMeasureSpec, heightMeasureSpec);
114         }
115     }
116 
117     @Override
handleStateChanged(QSTile.State state)118     protected void handleStateChanged(QSTile.State state) {
119         super.handleStateChanged(state);
120         if (!Objects.equals(mLabel.getText(), state.label) || mState != state.state) {
121             mLabel.setTextColor(state.state == Tile.STATE_UNAVAILABLE ? mColorLabelUnavailable
122                     : mColorLabelDefault);
123             mState = state.state;
124             mLabel.setText(state.label);
125         }
126         if (!Objects.equals(mSecondLine.getText(), state.secondaryLabel)) {
127             mSecondLine.setText(state.secondaryLabel);
128             mSecondLine.setVisibility(TextUtils.isEmpty(state.secondaryLabel) ? View.GONE
129                     : View.VISIBLE);
130         }
131         boolean dualTarget = DUAL_TARGET_ALLOWED && state.dualTarget;
132         mExpandIndicator.setVisibility(dualTarget ? View.VISIBLE : View.GONE);
133         mExpandSpace.setVisibility(dualTarget ? View.VISIBLE : View.GONE);
134         mLabelContainer.setContentDescription(dualTarget ? state.dualLabelContentDescription
135                 : null);
136         if (dualTarget != mLabelContainer.isClickable()) {
137             mLabelContainer.setClickable(dualTarget);
138             mLabelContainer.setLongClickable(dualTarget);
139             mLabelContainer.setBackground(dualTarget ? newTileBackground() : null);
140         }
141         mLabel.setEnabled(!state.disabledByPolicy);
142         mPadLock.setVisibility(state.disabledByPolicy ? View.VISIBLE : View.GONE);
143     }
144 
145     @Override
init(OnClickListener click, OnClickListener secondaryClick, OnLongClickListener longClick)146     public void init(OnClickListener click, OnClickListener secondaryClick,
147             OnLongClickListener longClick) {
148         super.init(click, secondaryClick, longClick);
149         mLabelContainer.setOnClickListener(secondaryClick);
150         mLabelContainer.setOnLongClickListener(longClick);
151         mLabelContainer.setClickable(false);
152         mLabelContainer.setLongClickable(false);
153     }
154 }
155