1 /*
2  * Copyright (C) 2018 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.statusbar;
18 
19 import static com.android.systemui.plugins.DarkIconDispatcher.getTint;
20 import static com.android.systemui.plugins.DarkIconDispatcher.isInArea;
21 import static com.android.systemui.statusbar.StatusBarIconView.STATE_DOT;
22 import static com.android.systemui.statusbar.StatusBarIconView.STATE_HIDDEN;
23 import static com.android.systemui.statusbar.StatusBarIconView.STATE_ICON;
24 
25 import android.content.Context;
26 import android.content.res.ColorStateList;
27 import android.graphics.Rect;
28 import android.util.AttributeSet;
29 import android.view.Gravity;
30 import android.view.LayoutInflater;
31 import android.view.View;
32 import android.widget.FrameLayout;
33 import android.widget.ImageView;
34 import android.widget.LinearLayout;
35 
36 import com.android.systemui.R;
37 import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver;
38 import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.WifiIconState;
39 
40 /**
41  * Start small: StatusBarWifiView will be able to layout from a WifiIconState
42  */
43 public class StatusBarWifiView extends FrameLayout implements DarkReceiver,
44         StatusIconDisplayable {
45     private static final String TAG = "StatusBarWifiView";
46 
47     /// Used to show etc dots
48     private StatusBarIconView mDotView;
49     /// Contains the main icon layout
50     private LinearLayout mWifiGroup;
51     private ImageView mWifiIcon;
52     private ImageView mIn;
53     private ImageView mOut;
54     private View mInoutContainer;
55     private View mSignalSpacer;
56     private View mAirplaneSpacer;
57     private WifiIconState mState;
58     private String mSlot;
59     private int mVisibleState = -1;
60 
fromContext(Context context, String slot)61     public static StatusBarWifiView fromContext(Context context, String slot) {
62         LayoutInflater inflater = LayoutInflater.from(context);
63         StatusBarWifiView v = (StatusBarWifiView) inflater.inflate(R.layout.status_bar_wifi_group, null);
64         v.setSlot(slot);
65         v.init();
66         v.setVisibleState(STATE_ICON);
67         return v;
68     }
69 
StatusBarWifiView(Context context)70     public StatusBarWifiView(Context context) {
71         super(context);
72     }
73 
StatusBarWifiView(Context context, AttributeSet attrs)74     public StatusBarWifiView(Context context, AttributeSet attrs) {
75         super(context, attrs);
76     }
77 
StatusBarWifiView(Context context, AttributeSet attrs, int defStyleAttr)78     public StatusBarWifiView(Context context, AttributeSet attrs, int defStyleAttr) {
79         super(context, attrs, defStyleAttr);
80     }
81 
StatusBarWifiView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)82     public StatusBarWifiView(Context context, AttributeSet attrs, int defStyleAttr,
83             int defStyleRes) {
84         super(context, attrs, defStyleAttr, defStyleRes);
85     }
86 
setSlot(String slot)87     public void setSlot(String slot) {
88         mSlot = slot;
89     }
90 
91     @Override
setStaticDrawableColor(int color)92     public void setStaticDrawableColor(int color) {
93         ColorStateList list = ColorStateList.valueOf(color);
94         mWifiIcon.setImageTintList(list);
95         mIn.setImageTintList(list);
96         mOut.setImageTintList(list);
97         mDotView.setDecorColor(color);
98     }
99 
100     @Override
setDecorColor(int color)101     public void setDecorColor(int color) {
102         mDotView.setDecorColor(color);
103     }
104 
105     @Override
getSlot()106     public String getSlot() {
107         return mSlot;
108     }
109 
110     @Override
isIconVisible()111     public boolean isIconVisible() {
112         return mState != null && mState.visible;
113     }
114 
115     @Override
setVisibleState(int state, boolean animate)116     public void setVisibleState(int state, boolean animate) {
117         if (state == mVisibleState) {
118             return;
119         }
120         mVisibleState = state;
121 
122         switch (state) {
123             case STATE_ICON:
124                 mWifiGroup.setVisibility(View.VISIBLE);
125                 mDotView.setVisibility(View.GONE);
126                 break;
127             case STATE_DOT:
128                 mWifiGroup.setVisibility(View.GONE);
129                 mDotView.setVisibility(View.VISIBLE);
130                 break;
131             case STATE_HIDDEN:
132             default:
133                 mWifiGroup.setVisibility(View.GONE);
134                 mDotView.setVisibility(View.GONE);
135                 break;
136         }
137     }
138 
139     @Override
getVisibleState()140     public int getVisibleState() {
141         return mVisibleState;
142     }
143 
144     @Override
getDrawingRect(Rect outRect)145     public void getDrawingRect(Rect outRect) {
146         super.getDrawingRect(outRect);
147         float translationX = getTranslationX();
148         float translationY = getTranslationY();
149         outRect.left += translationX;
150         outRect.right += translationX;
151         outRect.top += translationY;
152         outRect.bottom += translationY;
153     }
154 
init()155     private void init() {
156         mWifiGroup = findViewById(R.id.wifi_group);
157         mWifiIcon = findViewById(R.id.wifi_signal);
158         mIn = findViewById(R.id.wifi_in);
159         mOut = findViewById(R.id.wifi_out);
160         mSignalSpacer = findViewById(R.id.wifi_signal_spacer);
161         mAirplaneSpacer = findViewById(R.id.wifi_airplane_spacer);
162         mInoutContainer = findViewById(R.id.inout_container);
163 
164         initDotView();
165     }
166 
initDotView()167     private void initDotView() {
168         mDotView = new StatusBarIconView(mContext, mSlot, null);
169         mDotView.setVisibleState(STATE_DOT);
170 
171         int width = mContext.getResources().getDimensionPixelSize(R.dimen.status_bar_icon_size);
172         LayoutParams lp = new LayoutParams(width, width);
173         lp.gravity = Gravity.CENTER_VERTICAL | Gravity.START;
174         addView(mDotView, lp);
175     }
176 
applyWifiState(WifiIconState state)177     public void applyWifiState(WifiIconState state) {
178         boolean requestLayout = false;
179 
180         if (state == null) {
181             requestLayout = getVisibility() != View.GONE;
182             setVisibility(View.GONE);
183             mState = null;
184         } else if (mState == null) {
185             requestLayout = true;
186             mState = state.copy();
187             initViewState();
188         } else if (!mState.equals(state)) {
189             requestLayout = updateState(state.copy());
190         }
191 
192         if (requestLayout) {
193             requestLayout();
194         }
195     }
196 
updateState(WifiIconState state)197     private boolean updateState(WifiIconState state) {
198         setContentDescription(state.contentDescription);
199         if (mState.resId != state.resId && state.resId >= 0) {
200             mWifiIcon.setImageDrawable(mContext.getDrawable(state.resId));
201         }
202 
203         mIn.setVisibility(state.activityIn ? View.VISIBLE : View.GONE);
204         mOut.setVisibility(state.activityOut ? View.VISIBLE : View.GONE);
205         mInoutContainer.setVisibility(
206                 (state.activityIn || state.activityOut) ? View.VISIBLE : View.GONE);
207         mAirplaneSpacer.setVisibility(state.airplaneSpacerVisible ? View.VISIBLE : View.GONE);
208         mSignalSpacer.setVisibility(state.signalSpacerVisible ? View.VISIBLE : View.GONE);
209 
210         boolean needsLayout = state.activityIn != mState.activityIn
211                 ||state.activityOut != mState.activityOut;
212 
213         if (mState.visible != state.visible) {
214             needsLayout |= true;
215             setVisibility(state.visible ? View.VISIBLE : View.GONE);
216         }
217 
218         mState = state;
219         return needsLayout;
220     }
221 
initViewState()222     private void initViewState() {
223         setContentDescription(mState.contentDescription);
224         if (mState.resId >= 0) {
225             mWifiIcon.setImageDrawable(mContext.getDrawable(mState.resId));
226         }
227 
228         mIn.setVisibility(mState.activityIn ? View.VISIBLE : View.GONE);
229         mOut.setVisibility(mState.activityOut ? View.VISIBLE : View.GONE);
230         mInoutContainer.setVisibility(
231                 (mState.activityIn || mState.activityOut) ? View.VISIBLE : View.GONE);
232         mAirplaneSpacer.setVisibility(mState.airplaneSpacerVisible ? View.VISIBLE : View.GONE);
233         mSignalSpacer.setVisibility(mState.signalSpacerVisible ? View.VISIBLE : View.GONE);
234         setVisibility(mState.visible ? View.VISIBLE : View.GONE);
235     }
236 
237     @Override
onDarkChanged(Rect area, float darkIntensity, int tint)238     public void onDarkChanged(Rect area, float darkIntensity, int tint) {
239         int areaTint = getTint(area, this, tint);
240         ColorStateList color = ColorStateList.valueOf(areaTint);
241         mWifiIcon.setImageTintList(color);
242         mIn.setImageTintList(color);
243         mOut.setImageTintList(color);
244         mDotView.setDecorColor(areaTint);
245         mDotView.setIconColor(areaTint, false);
246     }
247 
248 
249     @Override
toString()250     public String toString() {
251         return "StatusBarWifiView(slot=" + mSlot + " state=" + mState + ")";
252     }
253 }
254