1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.systemui.qs;
18 
19 import android.animation.ValueAnimator;
20 import android.content.Context;
21 import android.graphics.drawable.Drawable;
22 import android.view.View;
23 import android.widget.FrameLayout;
24 import android.widget.ImageView;
25 
26 import com.android.systemui.R;
27 import com.android.systemui.qs.QSTile.SignalState;
28 
29 /** View that represents a custom quick settings tile for displaying signal info (wifi/cell). **/
30 public final class SignalTileView extends QSTileView {
31     private static final long DEFAULT_DURATION = new ValueAnimator().getDuration();
32     private static final long SHORT_DURATION = DEFAULT_DURATION / 3;
33 
34     private FrameLayout mIconFrame;
35     private ImageView mSignal;
36     private ImageView mOverlay;
37     private ImageView mIn;
38     private ImageView mOut;
39 
40     private int mWideOverlayIconStartPadding;
41 
SignalTileView(Context context)42     public SignalTileView(Context context) {
43         super(context);
44 
45         mIn = addTrafficView(R.drawable.ic_qs_signal_in);
46         mOut = addTrafficView(R.drawable.ic_qs_signal_out);
47 
48         mWideOverlayIconStartPadding = context.getResources().getDimensionPixelSize(
49                 R.dimen.wide_type_icon_start_padding_qs);
50     }
51 
addTrafficView(int icon)52     private ImageView addTrafficView(int icon) {
53         final ImageView traffic = new ImageView(mContext);
54         traffic.setImageResource(icon);
55         traffic.setAlpha(0f);
56         addView(traffic);
57         return traffic;
58     }
59 
60     @Override
createIcon()61     protected View createIcon() {
62         mIconFrame = new FrameLayout(mContext);
63         mSignal = new ImageView(mContext);
64         mIconFrame.addView(mSignal);
65         mOverlay = new ImageView(mContext);
66         mIconFrame.addView(mOverlay, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
67         return mIconFrame;
68     }
69 
70     @Override
onMeasure(int widthMeasureSpec, int heightMeasureSpec)71     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
72         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
73         int hs = MeasureSpec.makeMeasureSpec(mIconFrame.getMeasuredHeight(), MeasureSpec.EXACTLY);
74         int ws = MeasureSpec.makeMeasureSpec(mIconFrame.getMeasuredHeight(), MeasureSpec.AT_MOST);
75         mIn.measure(ws, hs);
76         mOut.measure(ws, hs);
77     }
78 
79     @Override
onLayout(boolean changed, int l, int t, int r, int b)80     protected void onLayout(boolean changed, int l, int t, int r, int b) {
81         super.onLayout(changed, l, t, r, b);
82         layoutIndicator(mIn);
83         layoutIndicator(mOut);
84     }
85 
layoutIndicator(View indicator)86     private void layoutIndicator(View indicator) {
87         boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
88         int left, right;
89         if (isRtl) {
90             right = mIconFrame.getLeft();
91             left = right - indicator.getMeasuredWidth();
92         } else {
93             left = mIconFrame.getRight();
94             right = left + indicator.getMeasuredWidth();
95         }
96         indicator.layout(
97                 left,
98                 mIconFrame.getBottom() - indicator.getMeasuredHeight(),
99                 right,
100                 mIconFrame.getBottom());
101     }
102 
103     @Override
handleStateChanged(QSTile.State state)104     protected void handleStateChanged(QSTile.State state) {
105         super.handleStateChanged(state);
106         final SignalState s = (SignalState) state;
107         setIcon(mSignal, s);
108         if (s.overlayIconId > 0) {
109             mOverlay.setVisibility(VISIBLE);
110             mOverlay.setImageResource(s.overlayIconId);
111         } else {
112             mOverlay.setVisibility(GONE);
113         }
114         if (s.overlayIconId > 0 && s.isOverlayIconWide) {
115             mSignal.setPaddingRelative(mWideOverlayIconStartPadding, 0, 0, 0);
116         } else {
117             mSignal.setPaddingRelative(0, 0, 0, 0);
118         }
119         Drawable drawable = mSignal.getDrawable();
120         if (state.autoMirrorDrawable && drawable != null) {
121             drawable.setAutoMirrored(true);
122         }
123         final boolean shown = isShown();
124         setVisibility(mIn, shown, s.activityIn);
125         setVisibility(mOut, shown, s.activityOut);
126     }
127 
setVisibility(View view, boolean shown, boolean visible)128     private void setVisibility(View view, boolean shown, boolean visible) {
129         final float newAlpha = shown && visible ? 1 : 0;
130         if (view.getAlpha() == newAlpha) return;
131         if (shown) {
132             view.animate()
133                 .setDuration(visible ? SHORT_DURATION : DEFAULT_DURATION)
134                 .alpha(newAlpha)
135                 .start();
136         } else {
137             view.setAlpha(newAlpha);
138         }
139     }
140 }
141